From Erik Habbinga:
[mirror/scst/.git] / mpt / mpt_scst.c
1 /*
2  *  mpt_scst.c
3  *
4  *  Copyright (C) 2005 Beijing Soul Technology Co., Ltd.
5  *  Copyright (C) 2002, 2003, 2004 LSI Logic Corporation
6  *  Copyright (C) 2004 Vladislav Bolkhovitin <vst@vlnb.net>
7  *                and Leonid Stoljar
8  *
9  *  MPT SCSI target mode driver for SCST.
10  * 
11  *  Originally   By: Stephen Shirron
12  *  Port to SCST By: Hu Gang <hugang@soulinfo.com>
13  *
14  *  This program is free software; you can redistribute it and/or
15  *  modify it under the terms of the GNU General Public License
16  *  as published by the Free Software Foundation; either version 2
17  *  of the License, or (at your option) any later version.
18  * 
19  *  This program is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  *  GNU General Public License for more details.
23  *
24  */
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/types.h>
28 #include <linux/version.h>
29 #include <linux/blkdev.h>
30 #include <linux/interrupt.h>
31 #include <scsi/scsi.h>
32 #include <linux/seq_file.h>
33 #include <scsi/scsi_host.h>
34
35 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
36 #include <linux/pci.h>
37 #endif
38
39 #include "scsi_tgt.h"
40
41 #include <scst_debug.h>
42
43 #include "mpt_scst.h"
44
45 #define MYNAM "mpt_scst"
46
47 #ifdef TRACING
48 static int trace_mpi = 0;
49
50 #define TRACE_MPI       0x80000000
51
52 #endif
53
54 #ifdef DEBUG
55 static char *mpt_state_string[] = {
56         "0",
57         "new",
58         "need data",
59         "data in",
60         "data out",
61         "processed",
62         "NULL",
63 };
64 #endif
65
66 #ifdef DEBUG
67 #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
68         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_DEBUG | \
69         TRACE_MINOR | TRACE_SPECIAL)
70 #else
71 # ifdef TRACING
72 #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
73         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL)
74 # endif
75 #endif
76
77 static MPT_STM_PRIV *mpt_stm_priv[MPT_MAX_ADAPTERS+1];
78
79 static int set_aliases_in_fcportpage1 = 1;
80 static int num_aliases = 0;
81 static int stm_context = 0;
82
83 static int mpt_stm_adapter_online(MPT_STM_PRIV *priv);
84 static void mpt_stm_adapter_dispose(MPT_STM_PRIV *priv);
85 static int mpt_stm_adapter_install(MPT_ADAPTER *ioc);
86
87 static int __init _mpt_stm_init(void);
88
89 static void stmapp_set_status(MPT_STM_PRIV *priv, CMD *cmd, int status);
90 static void stmapp_tgt_command(MPT_STM_PRIV *priv, u32 reply_word);
91 static void stm_cmd_buf_post(MPT_STM_PRIV *priv, int index);
92
93 static void stm_tgt_reply_high_pri(MPT_ADAPTER *ioc, 
94                 TargetCmdBufferPostErrorReply_t *rep);
95 static void stm_target_reply_error(MPT_ADAPTER *ioc, TargetErrorReply_t *rep);
96 static void stmapp_target_error(MPT_STM_PRIV *priv, u32 reply_word, int index,
97                 int status, int reason);
98 static void stm_link_service_reply(MPT_ADAPTER *ioc,
99                        LinkServiceBufferPostReply_t *rep);
100 static void stm_link_service_rsp_reply(MPT_ADAPTER *ioc,
101                            LinkServiceRspRequest_t *req, LinkServiceRspReply_t *rep);
102 static void stmapp_set_sense_info(MPT_STM_PRIV *priv,
103                       CMD *cmd, int sense_key, int asc, int ascq);
104 static void stmapp_srr_adjust_offset(MPT_STM_PRIV *priv, int index);
105 static void stmapp_srr_convert_ta_to_tss(MPT_STM_PRIV *priv, int index);
106 static void stmapp_abts_process(MPT_STM_PRIV *priv,
107                     int rx_id, LinkServiceBufferPostReply_t *rep, int index);
108 static int stm_do_config_action(MPT_STM_PRIV *priv,
109                      int action, int type, int number, int address, int length,
110                      int sleep);
111 static int stm_get_config_page(MPT_STM_PRIV *priv,
112                     int type, int number, int address, int sleep);
113 static int stm_set_config_page(MPT_STM_PRIV *priv,
114                     int type, int number, int address, int sleep);
115 static void stm_cmd_buf_post_list(MPT_STM_PRIV *priv, int index);
116 static int stm_send_target_status(MPT_STM_PRIV *priv,
117                        u32 reply_word, int index, int flags, int lun, int tag);
118 static void stm_send_els(MPT_STM_PRIV *priv, LinkServiceBufferPostReply_t *rep,
119              int index, int length);
120 static void stm_link_serv_buf_post(MPT_STM_PRIV *priv, int index);
121
122 static void stm_wait(MPT_STM_PRIV *priv, int milliseconds, int sleep);
123 static int stm_wait_for(MPT_STM_PRIV *priv, volatile int *flag, int seconds,
124              int sleep);
125 static void stmapp_srr_process(MPT_STM_PRIV *priv, int rx_id, int r_ctl, 
126                 u32 offset, LinkServiceBufferPostReply_t *rep, int index);
127 static void stm_set_scsi_port_page1(MPT_STM_PRIV *priv, int sleep);
128
129 #ifdef DEBUG
130 #define trace_flag mpt_trace_flag
131 unsigned long mpt_trace_flag = TRACE_FUNCTION | TRACE_OUT_OF_MEM | TRACE_SPECIAL;
132 #else
133 # ifdef TRACING
134 #define trace_flag mpt_trace_flag
135 unsigned long mpt_trace_flag = TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_SPECIAL;
136 # endif
137 #endif
138
139 static int
140 mpt_target_show(struct seq_file *seq, void *v)
141 {
142         struct mpt_tgt *tgt = (struct mpt_tgt *)seq->private;
143         MPT_ADAPTER *ioc = tgt->priv->ioc;
144         MPT_STM_PRIV *priv = tgt->priv;
145
146         TRACE_ENTRY();
147         TRACE_DBG("priv %p, tgt %p", priv, tgt); 
148
149         sBUG_ON(tgt == NULL);
150         sBUG_ON(ioc == NULL);
151
152         seq_printf(seq, "ProductID        :0x%04x (%s)\n"
153                         "Target Enable    :%s\n",
154                         ioc->facts.ProductID,
155                         ioc->prod_name,
156                         tgt->target_enable ? "True" : "False");
157
158         if (ioc->bus_type == SCSI) {
159                 int i = 0;
160                 seq_printf(seq, "Target ID        :%d\n"
161                                 "Capabilities     :0x%x\n"
162                                 "PhysicalInterface:0x%x\n",
163                                 priv->port_id,
164                                 priv->SCSIPortPage0.Capabilities,
165                                 priv->SCSIPortPage0.PhysicalInterface);
166
167                 seq_printf(seq, "Configuration    :0x%x\n"
168                                 "OnBusTimerValue  :0x%x\n"
169                                 "TargetConfig     :0x%x\n"
170                                 "IDConfig         :0x%x\n",
171                                 priv->SCSIPortPage1.Configuration,
172                                 priv->SCSIPortPage1.OnBusTimerValue,
173                                 priv->SCSIPortPage1.TargetConfig,
174                                 priv->SCSIPortPage1.IDConfig);
175
176                 seq_printf(seq, "PortFlags        :0x%x\n"
177                                 "PortSettings     :0x%x\n",
178                                 priv->SCSIPortPage2.PortFlags,
179                                 priv->SCSIPortPage2.PortSettings);
180 #if 0
181                 for (i = 0; i < 16; i++) {
182                         seq_printf(seq, " DeviceSeting %02d: 0x%x 0x%x 0x%x\n",
183                                         priv->SCSIPortPage2.DeviceSettings[i].Timeout,
184                                         priv->SCSIPortPage2.DeviceSettings[i].SyncFactor,
185                                         priv->SCSIPortPage2.DeviceSettings[i].DeviceFlags);
186                 }
187 #endif
188                 for (i = 0; i < NUM_SCSI_DEVICES; i++) {
189                         seq_printf(seq, "  Device %02d: 0x%x, 0x%x\n",
190                                         i,
191                                         priv->SCSIDevicePage1[i].RequestedParameters,
192                                         priv->SCSIDevicePage1[i].Configuration);
193                 }
194         }
195
196         if (ioc->bus_type == FC) {
197                 seq_printf(seq, "WWN              :%08X%08X:%08X%08X\n",
198                                 ioc->fc_port_page0[0].WWNN.High,
199                                 ioc->fc_port_page0[0].WWNN.Low,
200                                 ioc->fc_port_page0[0].WWPN.High,
201                                 ioc->fc_port_page0[0].WWPN.Low);
202         }
203
204         TRACE_EXIT();
205         return 0;
206 }
207
208 static int
209 mpt_proc_target_write(struct file *file, const char __user *buf, 
210                         size_t length, loff_t *off)
211 {
212
213         struct mpt_tgt *tgt = (struct mpt_tgt *)PDE(file->f_dentry->d_inode)->data;
214         MPT_ADAPTER *ioc = tgt->priv->ioc;
215         int res = 0;
216         char tmp[32+1];
217
218         TRACE_ENTRY();
219         res = min(32, (int)length);
220         if (copy_from_user(tmp, buf, res)) {
221                 res = -EFAULT;
222                 goto out;
223         }
224         tmp[res] = 0;
225
226         TRACE_DBG("buff '%s'", tmp);
227         if (strncmp("target:enable", tmp, strlen("target:enable")) == 0) {
228                 TRACE_DBG("Enable Target, %d, %d", ioc->id, tgt->target_enable);
229                 if (tgt->target_enable != 1) {
230                         mpt_stm_adapter_online(mpt_stm_priv[ioc->id]);
231                         tgt->target_enable = 1;
232                 }
233         }
234
235         if (strncmp("target:disable", tmp, strlen("target:disable")) == 0) {
236                 TRACE_DBG("Disable Target %d, %d", ioc->id, tgt->target_enable);
237                 if (tgt->target_enable != 0) {
238                         /* FIXME */
239                         tgt->target_enable = 0;
240                 }
241         }
242
243         if (strncmp("target_id:", tmp, strlen("target_id:")) == 0) {
244                 char *s = tmp + strlen("target_id:");
245                 int id = simple_strtoul(s, NULL, 0);
246                 if (id < MPT_MAX_SCSI_DEVICES) {
247                         if (IsScsi(tgt->priv)) {
248                                 TRACE_DBG("Changing target id to %d\n", 
249                                                 id);
250                                 tgt->priv->port_id = id;
251                                 stm_set_scsi_port_page1(tgt->priv, 
252                                                 NO_SLEEP);
253                         }
254                 }
255         }
256
257 out:
258         TRACE_EXIT_RES(res);
259
260         return length;
261 }
262
263 static struct scst_proc_data mpt_target_proc_data = {
264         SCST_DEF_RW_SEQ_OP(mpt_proc_target_write)
265         .show = mpt_target_show,
266 };
267
268 static int mpt_target_detect(struct scst_tgt_template *temp1);
269 static int mpt_target_release(struct scst_tgt *scst_tgt);
270 static int stmapp_pending_sense(struct mpt_cmd *mpt_cmd);
271 static int mpt_xmit_response(struct scst_cmd *scst_cmd);
272 static void mpt_inquiry_no_tagged_commands(MPT_STM_PRIV *priv, 
273                 struct scst_cmd *scst_cmd);
274 static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd);
275 static void mpt_on_free_cmd(struct scst_cmd *scst_cmd);
276 static void mpt_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd);
277 static int mpt_handle_task_mgmt(MPT_STM_PRIV * priv, u32 reply_word,
278                 int task_mgmt, int lun);
279 static int mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context);
280
281 static struct scst_tgt_template tgt_template = {
282         .name = MYNAM,
283         .sg_tablesize = 128, /* FIXME */
284         .use_clustering = 1,
285 #ifdef DEBUG_WORK_IN_THREAD
286         .xmit_response_atomic = 0,
287         .rdy_to_xfer_atomic = 0,
288 #else
289         .xmit_response_atomic = 1,
290         .rdy_to_xfer_atomic = 1,
291 #endif
292         .detect = mpt_target_detect,
293         .release = mpt_target_release,
294         .xmit_response = mpt_xmit_response,
295         .rdy_to_xfer = mpt_rdy_to_xfer,
296         .on_free_cmd = mpt_on_free_cmd,
297         .task_mgmt_fn_done = mpt_task_mgmt_fn_done,
298 };
299
300 static inline void 
301 mpt_msg_frame_free(MPT_STM_PRIV *priv, int index)
302 {
303         MPT_ADAPTER *ioc = priv->ioc;
304         if (priv->current_mf[index] != NULL) {
305                 TRACE_DBG("%s: free mf index %d, %p", ioc->name,
306                                 MF_TO_INDEX(priv->current_mf[index]), 
307                                 priv->current_mf[index]);
308                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
309                 priv->current_mf[index] = NULL;
310         }
311 }
312
313 static inline MPT_FRAME_HDR *
314 mpt_msg_frame_alloc(MPT_ADAPTER *ioc, int index)
315 {
316         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
317         MPT_FRAME_HDR *mf;
318
319         if (index != -1) {
320                 TRACE_DBG("%s: current_mf %p, index %d", 
321                                 ioc->name, priv->current_mf[index], index);
322                 WARN_ON(priv->current_mf[index] != NULL);
323         }
324
325         mf = mpt_get_msg_frame(stm_context, _IOC_ID);
326
327         if (mf == NULL) {
328                 sBUG_ON(1);
329         }
330         
331         if (index != -1) {
332                 priv->current_mf[index] = mf;
333         }
334
335         TRACE_DBG("%s: alloc mf index %d, %p, %d", ioc->name, 
336                         MF_TO_INDEX(mf), mf, index);
337
338         return mf;
339 }
340
341 static int _mpt_ada_nums = 0;
342
343 static int
344 mptstm_probe(struct pci_dev *pdev, const struct pci_device_id *id)
345 {
346     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
347     int ret = 0;
348     struct mpt_tgt *tgt;
349     struct proc_dir_entry *p;
350     struct proc_dir_entry *root;
351     char name[4];
352     
353     TRACE_ENTRY();
354     ret = mpt_stm_adapter_install(ioc);
355     if (ret != 0) {
356             goto out;
357     }
358
359     tgt = kmalloc(sizeof(*tgt), GFP_KERNEL);
360     TRACE_MEM("kmalloc(GFP_KERNEL) for tgt (%d), %p",
361               sizeof(*tgt), tgt);
362     if (tgt == NULL) {
363             TRACE(TRACE_OUT_OF_MEM, "%s",
364                   "Allocation of tgt failed");
365             ret = -ENOMEM;
366             goto out;
367     }
368     memset(tgt, 0, sizeof(*tgt));
369     tgt->priv = mpt_stm_priv[ioc->id];
370     tgt->target_enable = 0;
371     tgt->priv->port_id = 1;
372     /* tgt->priv->scsi_port_config = MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG; */
373     tgt->priv->scsi_port_config = MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY;
374     /* tgt->priv->scsi_id_config = 0x7; */
375     tgt->priv->scsi_id_config = 0;
376     atomic_set(&tgt->sess_count, 0);
377     init_waitqueue_head(&tgt->waitQ);
378     
379     tgt->scst_tgt = scst_register(&tgt_template);
380     if (tgt->scst_tgt == NULL) {
381             PRINT_ERROR(MYNAM ": scst_register() "
382                         "failed for host %p", pdev);
383             
384             ret = -ENODEV;
385             goto out;
386     }
387
388     root = scst_proc_get_tgt_root(&tgt_template);
389     scnprintf(name, sizeof(name), "%d", ioc->id);
390     mpt_target_proc_data.data = (void *)tgt;
391     p = scst_create_proc_entry(root, name,
392                                 &mpt_target_proc_data);
393     if (p == NULL) {
394             PRINT_ERROR("Not enough memory to register "
395                             "target driver %s entry %s in /proc",
396                             tgt_template.name, name);
397             scst_unregister(tgt->scst_tgt);
398             ret = -ENOMEM;
399             goto out;
400     }
401
402     scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
403     mpt_stm_priv[ioc->id]->tgt = tgt;
404     _mpt_ada_nums ++;
405                         
406  out:
407     
408     TRACE_EXIT_RES(ret);
409     
410     return ret;
411 }
412
413 static void
414 mptstm_remove(struct pci_dev *pdev)
415 {
416     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
417     MPT_STM_PRIV *priv;
418
419         priv = mpt_stm_priv[ioc->id];
420         if (priv != NULL) {
421                 mpt_stm_adapter_dispose(priv);
422         }
423 }
424
425 static struct mpt_pci_driver mptstm_driver = {
426     .probe = mptstm_probe,
427     .remove = mptstm_remove,
428 };
429
430 /*
431  * mpt_target_detect
432  *
433  * this function is intended to detect the target adapters that are present in
434  * the system. Each found adapter should be registered by calling
435  * scst_register(). The function should return a value >= 0 to signify
436  * the number of detected target adapters. A negative value should be
437  * returned whenever there is an error. 
438  */
439 static int mpt_target_detect(struct scst_tgt_template *templ)
440 {
441         int ret  = 0;
442
443         TRACE_ENTRY();
444         ret = _mpt_stm_init();
445         if (ret != 0) {
446                 goto out;
447         }
448
449         if (mpt_device_driver_register(&mptstm_driver, MPTSTM_DRIVER)) {
450                 printk(KERN_WARNING MYNAM
451                        ": failed to register for device driver callbacks\n");
452                 ret = -ENODEV;
453                 goto out;
454         }
455         
456         ret = _mpt_ada_nums;
457         
458  out:
459         TRACE_EXIT_RES(ret);
460         
461         return ret;
462 }
463
464 static struct scst_cmd *
465 _stm_target_command(MPT_STM_PRIV *priv, int reply_word, 
466                     struct mpt_cmd *mpt_cmd)
467 {
468         u8 *cdb;
469         int lun, tag, dl, alias, index, init_index, task_mgmt;
470         char alias_lun[32];
471         CMD *cmd;
472         struct scst_cmd *scst_cmd;
473         struct mpt_sess *sess = mpt_cmd->sess;
474 #ifdef DEBUG
475         MPT_ADAPTER *ioc = priv->ioc;
476 #endif
477         /* 
478          * Get the CBD, LUN, tag,  Task Mgmt flags, and data length from the 
479          * receive packet 
480          */
481         TRACE_ENTRY();
482
483         index = GET_IO_INDEX(reply_word);
484         init_index = GET_INITIATOR_INDEX(reply_word);
485
486         cmd = &priv->hw->cmd_buf[index];
487
488         if (IsScsi(priv)) {
489                 SCSI_CMD *scsi_cmd = (SCSI_CMD *)cmd->cmd;
490
491                 cdb = scsi_cmd->CDB;
492                 lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
493                 tag = scsi_cmd->Tag;
494                 task_mgmt = scsi_cmd->TaskManagementFlags;
495                 dl = 0;
496                 /*TRACE_DBG("AliasID %d, %d", scsi_cmd->AliasID, priv->port_id);*/
497                 if (reply_word & TARGET_MODE_REPLY_ALIAS_MASK) {
498                         alias = (scsi_cmd->AliasID - priv->port_id) & 15;
499                         sprintf(alias_lun, "alias %d lun %d", alias, lun);
500                 } else {
501                         alias = 0;
502                         sprintf(alias_lun, "lun %d", lun);
503                 }
504         } else if (IsSas(priv)) {
505                 SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
506
507                 cdb = ssp_cmd->CDB;
508                 lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
509                 if (ssp_cmd->FrameType == SSP_TASK_FRAME) {
510                         SSP_TASK        *ssp_task = (SSP_TASK *)cmd->cmd;
511
512                         tag = ssp_task->ManagedTaskTag;
513                         task_mgmt = ssp_task->TaskManagementFunction;
514                 } else {
515                         tag = ssp_cmd->InitiatorTag;
516                         task_mgmt = 0;
517                 }
518                 dl = 0;
519                 alias = 0;
520                 sprintf(alias_lun, "lun %d", lun);
521         } else {
522                 FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
523
524                 cdb = fcp_cmd->FcpCdb;
525                 lun = get2bytes(fcp_cmd->FcpLun, 0);
526                 tag = 0;
527                 task_mgmt = fcp_cmd->FcpCntl[2];
528                 dl = be32_to_cpu(fcp_cmd->FcpDl);
529                 if (reply_word & TARGET_MODE_REPLY_ALIAS_MASK) {
530                         alias = fcp_cmd->AliasIndex;
531                         sprintf(alias_lun, "alias %d lun %d", alias, lun);
532                 } else {
533                         alias = 0;
534                         sprintf(alias_lun, "lun %d", lun);
535                 }
536         }
537
538         cmd->reply_word = reply_word;
539         cmd->alias = alias;
540         cmd->lun = lun;
541         cmd->tag = tag;
542
543         TRACE_DBG("%s: cmd %p, re_word %x, alias %x, lun %x, tag %x,"
544                         "%s, init_idx %d, %p, %d",
545                         ioc->name, cmd, reply_word, alias, lun, tag, alias_lun, 
546                         init_index, priv->scst_cmd[index], dl);
547
548         mpt_cmd->CMD = cmd;
549         {
550                 uint16_t _lun = lun;
551                 _lun = swab16(le16_to_cpu(_lun));
552                 scst_cmd = scst_rx_cmd(sess->scst_sess, (uint8_t *)&_lun,
553                                 sizeof(_lun), cdb, MPT_MAX_CDB_LEN, SCST_ATOMIC);
554         }
555         if (scst_cmd == NULL) {
556                 PRINT_ERROR(MYNAM ": scst_rx_cmd() failed for %p", cmd);
557                 goto out;
558         }
559         TRACE_DBG("scst cmd %p, index %d", priv->scst_cmd[index], index);
560
561         WARN_ON(priv->scst_cmd[index] != 0);
562         priv->scst_cmd[index] = scst_cmd;
563
564         scst_cmd_set_tag(scst_cmd, tag);
565         scst_cmd_set_tgt_priv(scst_cmd, mpt_cmd);
566
567         /* FIXME scst_cmd_set_expected */
568 out:
569         TRACE_EXIT();
570
571         return scst_cmd;
572 }
573
574 static void
575 mpt_send_busy(struct mpt_cmd *cmd)
576 {
577         stmapp_set_status(cmd->priv, cmd->CMD, STS_BUSY);
578 }
579
580 static void 
581 mpt_alloc_session_done(struct scst_session *scst_sess, void *data, int result)
582 {
583         struct mpt_sess *sess = (struct mpt_sess *) data;
584         struct mpt_tgt *tgt = sess->tgt;
585         struct mpt_cmd *cmd = NULL;
586         int rc = 0;
587
588         TRACE_ENTRY();
589         if (result == 0) {
590                 scst_sess_set_tgt_priv(scst_sess, sess);
591                 
592                 while (!list_empty(&sess->delayed_cmds)) {
593                         cmd = list_entry(sess->delayed_cmds.next,
594                                          typeof(*cmd), delayed_cmds_entry);
595                         list_del(&cmd->delayed_cmds_entry);
596                         if (rc == 0)
597                                 rc = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_THREAD);
598                         if (rc != 0) {
599                                 PRINT_INFO(MYNAM ": Unable to get the command, sending BUSY state %p", 
600                                            cmd);
601                                 mpt_send_busy(cmd);
602                                 kfree(cmd);
603                         }
604                 }
605         } else {
606                 PRINT_INFO(MYNAM ": Session initialization failed, "
607                            "sending BUSY status to all deferred commands %p",
608                            cmd);
609                 while (!list_empty(&sess->delayed_cmds)) {
610                         cmd = list_entry(sess->delayed_cmds.next,
611                                          typeof(*cmd), delayed_cmds_entry);
612                         list_del(&cmd->delayed_cmds_entry);
613                         TRACE(TRACE_MGMT, "Command <%p> Busy", cmd);
614                         mpt_send_busy(cmd);
615                         kfree(cmd);
616                 }
617                 tgt->sess[sess->init_index] = NULL;
618                 
619                 TRACE_MEM("kfree for sess %p", sess);
620                 kfree(sess);
621                 
622                 if (atomic_dec_and_test(&tgt->sess_count))
623                                 wake_up_all(&tgt->waitQ);
624         }
625         
626         __clear_bit(MPT_SESS_INITING, &sess->sess_flags);
627
628         TRACE_EXIT();
629         return;
630 }
631
632 static int 
633 mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context)
634 {
635         int res = 0;
636         
637         TRACE_ENTRY();
638         
639         cmd->scst_cmd = _stm_target_command(cmd->priv, cmd->reply_word, cmd);
640         if (cmd->scst_cmd == NULL) {
641                 res = -EFAULT;
642                 goto out;
643         }
644 #ifdef DEBUG_WORK_IN_THREAD
645         context = SCST_CONTEXT_THREAD;
646 #endif
647         scst_cmd_init_done(cmd->scst_cmd, context);
648
649  out:   
650         TRACE_EXIT_RES(res);
651         
652         return res;
653 }
654
655 static void
656 stm_send_target_status_deferred(MPT_STM_PRIV *priv,
657                 u32 reply_word, int index)
658 {
659         int ret = 0;
660         MPT_ADAPTER         *ioc = priv->ioc;
661         MPT_FRAME_HDR       *mf;
662         TargetStatusSendRequest_t   *req;
663
664         TRACE_ENTRY();
665         mf = priv->status_deferred_mf[index];
666         TRACE_DBG("mf %p, index %d", mf, index);
667         req = (TargetStatusSendRequest_t *)mf;
668
669         priv->io_state[index] |= IO_STATE_STATUS_SENT;
670
671         priv->current_mf[index] = mf;
672         priv->status_deferred_mf[index] = NULL;
673         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
674                 ret = mpt_send_handshake_request(stm_context, _IOC_ID,
675                                 sizeof(*req), (u32 *)req _HS_SLEEP);
676         } else {
677                 mpt_put_msg_frame(stm_context, _IOC_ID, mf);
678         }
679
680         TRACE_EXIT_RES(ret);
681 }
682
683 static void
684 stm_data_done(MPT_ADAPTER *ioc, u32 reply_word, 
685                 struct scst_cmd *scst_cmd, struct mpt_cmd *cmd, int index)
686 {
687         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
688
689         TRACE_ENTRY();
690         TRACE_DBG("scst cmd %p, index %d, data done",  scst_cmd, index);
691
692         if (scst_cmd_get_resp_data_len(scst_cmd) > 0) {
693                 TRACE_DBG("clear the data flags <%p>", scst_cmd);
694                 sBUG_ON(scst_cmd_get_sg_cnt(scst_cmd) == 0);
695                 pci_unmap_sg(priv->ioc->pcidev,
696                         scst_cmd_get_sg(scst_cmd),
697                         scst_cmd_get_sg_cnt(scst_cmd),
698                         scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
699         }
700         TRACE_EXIT();
701 }
702
703 void 
704 stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
705 {
706         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
707         int index;
708         int init_index;
709         struct scst_cmd *scst_cmd;
710         struct mpt_cmd *cmd;
711         volatile int *io_state;
712         
713         TRACE_ENTRY();
714
715         index = GET_IO_INDEX(reply_word);
716         init_index = GET_INITIATOR_INDEX(reply_word);
717         scst_cmd = priv->scst_cmd[index];
718         io_state = priv->io_state + index;
719
720         TRACE_DBG("index %d, state %x, scst cmd %p, current_mf %p",
721                         index, *io_state, scst_cmd, priv->current_mf[index]);
722         /*
723          * if scst_cmd is NULL it show the command buffer not using by 
724          * SCST, let parse the CDB
725          */
726         if (scst_cmd == NULL) {
727                 WARN_ON((*io_state & ~IO_STATE_HIGH_PRIORITY) != IO_STATE_POSTED);
728                 *io_state &= ~IO_STATE_POSTED;
729         
730                 mpt_msg_frame_free(priv, index);
731
732                 stmapp_tgt_command(priv, reply_word);
733                 goto out;
734         }
735         
736         cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
737         TRACE_DBG("scst cmd %p, index %d, cmd %p, cmd state %s", 
738                   scst_cmd, index, cmd, mpt_state_string[cmd->state]);
739         
740         if (cmd->state == MPT_STATE_NEED_DATA) {
741                 int context = SCST_CONTEXT_TASKLET;
742                 int rx_status = SCST_RX_STATUS_SUCCESS;
743
744                 cmd->state = MPT_STATE_DATA_IN;
745
746 #ifdef DEBUG_WORK_IN_THREAD
747                 context = SCST_CONTEXT_THREAD;
748 #endif
749                 TRACE_DBG("Data received, context %x, rx_status %d",
750                                 context, rx_status);
751
752                 sBUG_ON(!(*io_state & IO_STATE_DATA_SENT));
753                 mpt_msg_frame_free(priv, index);
754                 if (*io_state & IO_STATE_DATA_SENT) {
755                         *io_state &= ~IO_STATE_DATA_SENT;
756                         stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
757                 }
758 #if 0
759                 if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
760                         TRACE_DBG("%s", "io state auto repost");
761                         *io_state = IO_STATE_POSTED;
762                 } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
763                         TRACE_DBG("%s", "io state");
764                         stm_cmd_buf_post(priv, index);
765                 }
766 #endif
767                 scst_rx_data(scst_cmd, rx_status, context);
768
769                 goto out;
770         }
771
772         if (*io_state & IO_STATE_STATUS_SENT) {
773                 /*
774                  *  status (and maybe data too) was being sent, so repost the
775                  *  command buffer
776                  */
777                 *io_state &= ~IO_STATE_STATUS_SENT;
778                 mpt_msg_frame_free(priv, index);
779                 if (*io_state & IO_STATE_DATA_SENT) {
780                         *io_state &= ~IO_STATE_DATA_SENT;
781                         stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
782                 }
783                 TRACE_DBG("set priv->scst_cmd[%d] = NULL", index);
784                 priv->scst_cmd[index] = NULL;
785                 if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
786                         TRACE_DBG("%s", "io state auto repost");
787                         *io_state = IO_STATE_POSTED;
788                 } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
789                         TRACE_DBG("%s", "io state");
790                         stm_cmd_buf_post(priv, index);
791                 }
792
793                 /*
794                  * figure out how we're handling cached sense data.
795                  */
796                 if (IsScsi(priv)) {
797                         switch (atomic_read(&priv->pending_sense[init_index])) {
798                                 /* attempt to send status and sense succeeded */
799                                 case MPT_STATUS_SENSE_ATTEMPT:
800                                         atomic_set(&priv->pending_sense[init_index], 
801                                                 MPT_STATUS_SENSE_IDLE);
802                                         scst_tgt_cmd_done(scst_cmd);
803                                         break;
804
805                                 /* we tried to send status and sense 
806                                  * simltaneously and failed.  Prepare to handle 
807                                  * the next command without SCST if it is 
808                                  * REQUEST_SENSE */
809                                 case MPT_STATUS_SENSE_NOT_SENT:
810                                         atomic_set(&priv->pending_sense[init_index], 
811                                                 MPT_STATUS_SENSE_HANDLE_RQ);
812                                         scst_tgt_cmd_done(scst_cmd);
813                                         break;
814
815                                 /* we've handled REQUEST_SENSE ourselves and
816                                  * we're done with the command.  Clean up */
817                                 case MPT_STATUS_SENSE_HANDLE_RQ:
818                                         TRACE_DBG("%s: clearing pending sense", 
819                                                         ioc->name);
820                                         atomic_set(&priv->pending_sense[init_index], 
821                                                         MPT_STATUS_SENSE_IDLE);
822                                         mpt_on_free_cmd(scst_cmd);
823                                         /* scst_cmd alloced in stmapp_pending_sense */
824                                         kfree(scst_cmd); 
825                                         break;
826
827                                 default:
828                                         /* nothing much to do here, we aren't 
829                                          * handling cached sense/status */
830                                         scst_tgt_cmd_done(scst_cmd);
831                                         break;
832                         }
833                 } else {
834                         scst_tgt_cmd_done(scst_cmd);
835                 }
836
837                 goto out;
838         }
839
840         /*
841          *  data (but not status) was being sent, so if status needs to be
842          *  set now, go ahead and do it; otherwise do nothing
843          */
844         if (*io_state & IO_STATE_DATA_SENT) {
845                 *io_state &= ~IO_STATE_DATA_SENT;
846                 mpt_msg_frame_free(priv, index);
847                 stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
848                 if (*io_state & IO_STATE_STATUS_DEFERRED) {
849                         *io_state &= ~IO_STATE_STATUS_DEFERRED;
850                         stm_send_target_status_deferred(priv, reply_word, index);
851                 }
852                 cmd->state = MPT_STATE_PROCESSED;
853                 goto out;
854         }
855
856         /*
857          * just insert into list
858          * bug how can i handle it 
859          */
860         if (*io_state == 0 && cmd->state == MPT_STATE_NEW) {
861                 WARN_ON(1);
862                 goto out;
863         }
864 #if 0
865         if (*io_state == IO_STATE_POSTED) {
866                 TRACE_DBG("%s", "io state posted");
867                 /*
868                  *  command buffer was posted, so we now have a SCSI command
869                  */
870                 *io_state &= ~IO_STATE_POSTED;
871                 goto out;
872         }
873 #endif
874         WARN_ON(1);
875  out:
876         
877         TRACE_EXIT();
878 }
879
880 static int 
881 mpt_is_task_mgm(MPT_STM_PRIV *priv, u32 reply_word, int *lun)
882 {
883         int task_mgmt = 0, index;
884         CMD *cmd;
885         //struct mpt_tgt *tgt = priv->tgt;
886
887         TRACE_ENTRY();
888
889         index = GET_IO_INDEX(reply_word);
890         cmd = &priv->hw->cmd_buf[index];
891
892         if (IsScsi(priv)) {
893                 SCSI_CMD *scsi_cmd = (SCSI_CMD *)cmd->cmd;
894                 task_mgmt = scsi_cmd->TaskManagementFlags;
895                 *lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
896         } else if (IsSas(priv)) {
897                 SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
898                 if (ssp_cmd->FrameType == SSP_TASK_FRAME) {
899                         SSP_TASK *ssp_task = (SSP_TASK *)cmd->cmd;
900                         task_mgmt = ssp_task->TaskManagementFunction;
901                 }
902                 *lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
903         } else {
904                 FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
905                 task_mgmt = fcp_cmd->FcpCntl[2];
906                 *lun = get2bytes(fcp_cmd->FcpLun, 0);
907         }
908         TRACE_EXIT_RES(task_mgmt);
909
910         return task_mgmt;
911 }
912
913 static void
914 stmapp_tgt_command(MPT_STM_PRIV *priv, u32 reply_word)
915 {
916         struct mpt_tgt *tgt = NULL;
917         struct mpt_sess *sess = NULL;
918         struct mpt_cmd *cmd = NULL;
919         int init_index, res = 0, task_mgmt, lun;
920
921         TRACE_ENTRY();
922         
923         tgt = priv->tgt;
924
925         task_mgmt = mpt_is_task_mgm(priv, reply_word, &lun);
926         if (task_mgmt) {
927                 mpt_handle_task_mgmt(priv, reply_word, task_mgmt, lun);
928         }
929         
930         init_index = GET_INITIATOR_INDEX(reply_word);
931         
932         if (test_bit(MPT_TGT_SHUTDOWN, &tgt->tgt_flags)) {
933                 TRACE_DBG("New command while the device %p is shutting down", tgt);
934                 res = -EFAULT;
935                 goto out;
936         }
937         
938         cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
939         TRACE_MEM("kmalloc(GFP_ATOMIC) for cmd (%d): %p", sizeof(*cmd), cmd);
940         if (cmd == NULL) {
941                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed");
942                 res = -ENOMEM;
943                 goto out;
944         }
945         
946         memset(cmd, 0, sizeof(*cmd));
947         cmd->priv = priv;
948         cmd->reply_word = reply_word;
949         cmd->state = MPT_STATE_NEW;
950
951         sess = tgt->sess[init_index];
952         if (sess == NULL) {
953                 sess = kmalloc(sizeof(*sess), GFP_ATOMIC);
954                 if (sess == NULL) {
955                         TRACE(TRACE_OUT_OF_MEM, "%s",
956                               "Allocation of sess failed");
957                         res = -ENOMEM;
958                         goto out_free_cmd;
959                 }
960                 /* WWPN */
961                 
962                 atomic_inc(&tgt->sess_count);
963                 smp_mb__after_atomic_inc();
964                 
965                 memset(sess, 0, sizeof(*sess));
966                 sess->tgt = tgt;
967                 sess->init_index = init_index;
968                 INIT_LIST_HEAD(&sess->delayed_cmds);
969                 
970                 sess->scst_sess = scst_register_session(tgt->scst_tgt, 1,
971                                                         "", sess, mpt_alloc_session_done);
972                 if (sess->scst_sess == NULL) {
973                         PRINT_ERROR(MYNAM ": scst_register_session failed %p", 
974                                     tgt);
975                         res = -EFAULT;
976                         goto out_free_sess;
977                 }
978                 
979                 __set_bit(MPT_SESS_INITING, &sess->sess_flags);
980                 
981                 tgt->sess[init_index] = sess;
982                 scst_sess_set_tgt_priv(sess->scst_sess, sess);
983                 
984                 cmd->sess = sess;
985                 list_add_tail(&cmd->delayed_cmds_entry, &sess->delayed_cmds);
986                 goto out;
987         }
988
989         /* seesion is ready let us do it */
990         cmd->sess = sess;
991         if (test_bit(MPT_SESS_INITING, &sess->sess_flags)) {
992                 list_add_tail(&cmd->delayed_cmds_entry, &sess->delayed_cmds);
993         } else {
994                 /* if there is pending sense left over from the last command,
995                  * we need to send that if this is a REQUEST SENSE command.
996                  * Otherwise send the command to SCST */
997                 if (!stmapp_pending_sense(cmd)) {
998                         res = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_TASKLET);
999                         /*res = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_DIRECT_ATOMIC);*/
1000                         if (res != 0)
1001                                 goto out_free_cmd;
1002                 }
1003         }
1004         
1005  out:
1006         TRACE_EXIT();
1007         return;
1008
1009  out_free_sess:
1010         TRACE_MEM("kfree for sess %p", sess);
1011         kfree(sess);
1012
1013         if (atomic_dec_and_test(&tgt->sess_count))
1014                 wake_up_all(&tgt->waitQ);
1015         /* go through */
1016  out_free_cmd:
1017         TRACE_MEM("kfree for cmd %p", cmd);
1018         kfree(cmd);
1019         goto out;
1020 }
1021
1022 /*
1023  * mpt_target_release
1024  * 
1025  * this function is
1026  * intended to free up the resources allocated to the device. The function
1027  * should return 0 to indicate successful release or a negative value if
1028  * there are some issues with the release. In the current version of SCST
1029  * the return value is ignored. Must be defined.
1030  */
1031 static int mpt_target_release(struct scst_tgt *scst_tgt)
1032 {
1033         /* FIXME */
1034         return 0;
1035 }
1036
1037 struct mpt_prm
1038 {
1039         struct mpt_tgt *tgt;
1040         uint16_t seg_cnt;
1041         unsigned short use_sg;
1042         struct scatterlist *sg;
1043         unsigned int bufflen;
1044         void *buffer;
1045         scst_data_direction data_direction;
1046         uint16_t rq_result;
1047         uint16_t scsi_status;
1048         unsigned char *sense_buffer;
1049         unsigned int sense_buffer_len;
1050         struct mpt_cmd *cmd;
1051 };
1052
1053 static inline void 
1054 mpt_dump_sge(MPT_SGE *sge, struct scatterlist *sg)
1055 {
1056         if (sge) {
1057                 void *address = NULL;
1058                 struct page *page = NULL;
1059                 address = bus_to_virt(sge->address);
1060                 page = virt_to_page(address);
1061                 TRACE_DBG("address %p, length %x, count %d, page %p", 
1062                                 address, sge->length, page_count(page), page);
1063                 TRACE_BUFFER("sge data", address, min(sge->length, (u32)0x10));
1064         }
1065         if (sg) {
1066                 TRACE_DBG("sg %p, page %p, %p, offset %d, dma address %x, len %d",
1067                                 sg, sg->page, page_address(sg->page), 
1068                                 sg->offset, sg->dma_address, sg->length);
1069                 TRACE_BUFFER("sg data", page_address(sg->page), (u32)0x10);
1070         }
1071 }
1072
1073 /* FIXME
1074  *
1075  * use_sg can not bigger then NUM_SGES
1076  *
1077  */
1078 static inline void
1079 mpt_sge_to_sgl(struct mpt_prm *prm, MPT_STM_PRIV *priv, MPT_SGL *sgl)
1080 {
1081         unsigned int bufflen = prm->bufflen;
1082         int i;
1083
1084         TRACE_ENTRY();
1085         TRACE_DBG("bufflen %d, %p", bufflen, prm->buffer);
1086         sBUG_ON(prm->use_sg == 0);
1087
1088         prm->sg = (struct scatterlist *)prm->buffer;
1089         prm->seg_cnt = pci_map_sg(priv->ioc->pcidev, prm->sg, prm->use_sg,
1090                                    scst_to_tgt_dma_dir(prm->data_direction));
1091                 
1092         pci_dma_sync_sg_for_cpu(priv->ioc->pcidev, prm->sg, prm->use_sg, 
1093                         scst_to_tgt_dma_dir(prm->data_direction));
1094         for (i = 0; i < prm->use_sg; i++) {
1095                 sgl->sge[i].length = sg_dma_len(&prm->sg[i]);
1096                 sgl->sge[i].address = sg_dma_address(&prm->sg[i]);
1097
1098                 TRACE_DBG("%d, %d", bufflen, prm->sg[i].length);
1099                 if (bufflen < prm->sg[i].length) {
1100                         sgl->sge[i].length = bufflen;
1101                 }
1102                 mpt_dump_sge(&sgl->sge[i], &prm->sg[i]);
1103                 bufflen -= sgl->sge[i].length;
1104         }
1105         pci_dma_sync_sg_for_device(priv->ioc->pcidev, prm->sg, prm->use_sg, 
1106                         scst_to_tgt_dma_dir(prm->data_direction));
1107         
1108         sgl->num_sges = prm->seg_cnt;
1109         
1110         TRACE_EXIT();
1111 }
1112
1113 static inline void
1114 mpt_set_sense_info(MPT_STM_PRIV *priv, CMD *cmd, int len, u8 *sense_buf)
1115 {
1116         u8 *info = NULL;
1117         
1118         TRACE_ENTRY();
1119
1120         if (IsScsi(priv)) {
1121                 SCSI_RSP    *rsp = (SCSI_RSP *)cmd->rsp;
1122
1123                 rsp->Status = STS_CHECK_CONDITION;
1124                 rsp->Valid |= SCSI_SENSE_LEN_VALID;
1125                 rsp->SenseDataListLength = cpu_to_be32(len);
1126                 info = rsp->SenseData;
1127                 if (rsp->Valid & SCSI_RSP_LEN_VALID) {
1128                         info += be32_to_cpu(rsp->PktFailuresListLength);
1129                 }
1130         } else if (IsSas(priv)) {
1131                 SSP_RSP     *rsp = (SSP_RSP *)cmd->rsp;
1132
1133                 rsp->Status = STS_CHECK_CONDITION;
1134                 rsp->DataPres |= SSP_SENSE_LEN_VALID;
1135                 rsp->SenseDataLength = cpu_to_be32(len);
1136                 info = rsp->ResponseSenseData;
1137                 if (rsp->DataPres & SSP_RSP_LEN_VALID) {
1138                         info += be32_to_cpu(rsp->ResponseDataLength);
1139                 }
1140         } else {
1141                 FCP_RSP     *rsp = (FCP_RSP *)cmd->rsp;
1142
1143                 rsp->FcpStatus = STS_CHECK_CONDITION;
1144                 rsp->FcpFlags |= FCP_SENSE_LEN_VALID;
1145                 rsp->FcpSenseLength = cpu_to_be32(len);
1146                 info = rsp->FcpSenseData - sizeof(rsp->FcpResponseData);
1147                 if (rsp->FcpFlags & FCP_RSP_LEN_VALID) {
1148                         info += be32_to_cpu(rsp->FcpResponseLength);
1149                 }
1150         }
1151
1152         sBUG_ON(info == NULL);
1153         memcpy(info, sense_buf, len);
1154 /*out:*/
1155
1156         TRACE_EXIT();
1157 }
1158
1159 static int
1160 mpt_send_tgt_data(MPT_STM_PRIV *priv, u32 reply_word,
1161                 int index, int flags, int lun, int tag, MPT_SGL *sgl,
1162                 int length, int offset)
1163 {
1164         MPT_ADAPTER *ioc = priv->ioc;
1165         TargetAssistRequest_t *req;
1166         MPT_STM_SIMPLE  *sge_simple;
1167         MPT_STM_CHAIN   *sge_chain = NULL;
1168         u32 sge_flags;
1169         int chain_length, i, j, k, init_index, res = 1;
1170         dma_addr_t dma_addr;
1171
1172         TRACE_ENTRY();
1173         req = (TargetAssistRequest_t *)mpt_msg_frame_alloc(ioc,index);
1174         memset(req, 0, sizeof(*req));
1175         
1176         if (priv->exiting) {
1177                 flags &= ~TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
1178         }
1179         
1180         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
1181                 flags |= TARGET_ASSIST_FLAGS_HIGH_PRIORITY;
1182                 if (flags & TARGET_ASSIST_FLAGS_AUTO_STATUS) {
1183                         flags |= TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
1184                         priv->io_state[index] |= IO_STATE_AUTO_REPOST;
1185                 }
1186         }
1187         
1188         if (priv->fcp2_capable/* && priv->initiators != NULL*/) {
1189                 init_index = GET_INITIATOR_INDEX(reply_word);
1190                 /*init = priv->initiators[init_index];
1191                 if (init != NULL && init->confirm_capable) {
1192                         flags |= TARGET_ASSIST_FLAGS_CONFIRMED;
1193                 }*/
1194         }
1195         TRACE_DBG("flags %x, tag %x, lun %x, offset %x, length %x",
1196                   flags, tag, lun, offset, length);
1197         
1198         req->StatusCode = 0;
1199         req->TargetAssistFlags = (u8)flags;
1200         req->Function = MPI_FUNCTION_TARGET_ASSIST;
1201         req->QueueTag = (u16)tag;
1202         req->ReplyWord = cpu_to_le32(reply_word);
1203         req->LUN[0] = (u8)(lun >> 8);
1204         req->LUN[1] = (u8)lun;
1205         req->RelativeOffset = cpu_to_le32(offset);
1206         req->DataLength = cpu_to_le32(length);
1207         sge_flags =
1208                 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1209                                   MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1210         if (flags & TARGET_ASSIST_FLAGS_DATA_DIRECTION)
1211                 sge_flags |= MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_HOST_TO_IOC);
1212         sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
1213         for (i = 0, j = 0, k = 0; i < (int)sgl->num_sges; i++, j++) {
1214                 if (k == 0) {
1215                         /* still in mf, haven't chained yet -- do we need to? */
1216                         if (j == priv->num_sge_target_assist) {
1217                                 /* yes, we need to chain */
1218                                 /* overwrite the last element in the mf with a chain */
1219                                 sge_chain = (MPT_STM_CHAIN *)(sge_simple - 1);
1220                                 sge_chain->Flags =
1221                                         (u8)(MPI_SGE_FLAGS_CHAIN_ELEMENT |
1222                                                  MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1223                                 dma_addr = priv->hw_dma +
1224                                         ((u8 *)priv->hw->cmd_buf[index].chain_sge - 
1225                                          (u8 *)priv->hw);
1226                                 stm_set_dma_addr(sge_chain->Address, dma_addr);
1227                                 /* set the "last element" flag in the mf */
1228                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain - 1);
1229                                 sge_simple->FlagsLength |=
1230                                         cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT));
1231                                 /* redo the last element in the mf */
1232                                 sge_simple =
1233                                         (MPT_STM_SIMPLE *)priv->hw->cmd_buf[index].chain_sge;
1234                                 sge_simple->FlagsLength =
1235                                         cpu_to_le32(sgl->sge[i-1].length | sge_flags);
1236                                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i-1].address);
1237                                 mpt_dump_sge(&sgl->sge[i-1], NULL);
1238                                 sge_simple++;
1239                                 /* say we've chained */
1240                                 req->ChainOffset =
1241                                         ((u8 *)sge_chain - (u8 *)req) / sizeof(u32);
1242                                 j = 1;
1243                                 k++;
1244                         }
1245                 } else {
1246                         /* now in chain, do we need to chain again? */
1247                         if (j == priv->num_sge_chain) {
1248                                 /* yes, we need to chain */
1249                                 /* fix up the previous chain element */
1250                                 chain_length = sizeof(MPT_STM_CHAIN) +
1251                                         (priv->num_sge_chain - 1) * sizeof(MPT_STM_SIMPLE);
1252                                 sge_chain->Length = cpu_to_le16(chain_length);
1253                                 sge_chain->NextChainOffset =
1254                                         (chain_length - sizeof(MPT_STM_CHAIN)) / sizeof(u32);
1255                                 /* overwrite the last element in the chain with another chain */
1256                                 sge_chain = (MPT_STM_CHAIN *)(sge_simple - 1);
1257                                 sge_chain->Flags =
1258                                         (u8)(MPI_SGE_FLAGS_CHAIN_ELEMENT |
1259                                                  MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1260                                 dma_addr = priv->hw_dma + ((u8 *)sge_simple - (u8 *)priv->hw);
1261                                 stm_set_dma_addr(sge_chain->Address, dma_addr);
1262                                 /* set the "last element" flag in the previous chain */
1263                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain - 1);
1264                                 sge_simple->FlagsLength |=
1265                                         cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT));
1266                                 /* redo the last element in the previous chain */
1267                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain + 1);
1268                                 sge_simple->FlagsLength =
1269                                         cpu_to_le32(sgl->sge[i-1].length | sge_flags);
1270                                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i-1].address);
1271                                 mpt_dump_sge(&sgl->sge[i-1], NULL);
1272                                 sge_simple++;
1273                                 /* say we've chained */
1274                                 j = 1;
1275                                 k++;
1276                         }
1277                 }
1278                 sge_simple->FlagsLength = cpu_to_le32(sgl->sge[i].length | sge_flags);
1279                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i].address);
1280                 mpt_dump_sge(&sgl->sge[i], NULL);
1281                 sge_simple++;
1282         }
1283         /* did we chain? */
1284         if (k != 0) {
1285                 /* fix up the last chain element */
1286                 sge_chain->Length = cpu_to_le16(j * sizeof(MPT_STM_SIMPLE));
1287                 sge_chain->NextChainOffset = 0;
1288         }
1289         /* fix up the last element */
1290         sge_simple--;
1291         sge_simple->FlagsLength |=
1292                 cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT |
1293                                               MPI_SGE_FLAGS_END_OF_BUFFER |
1294                      MPI_SGE_FLAGS_END_OF_LIST));
1295 #ifdef TRACING
1296 if(trace_mpi)
1297 {
1298         u32 *p = (u32 *)req;
1299         int i;
1300         //dma_addr_t _data;
1301         //u8 *_buf;
1302
1303         TRACE(TRACE_MPI, "%s stm_send_target_data %d",
1304                         ioc->name, index);
1305         for (i = 0; i < (sizeof(*req) - sizeof(req->SGL)) / 4; i++) {
1306                 TRACE(TRACE_MPI, "%s req[%02x] = %08x",
1307                                 ioc->name, i * 4, le32_to_cpu(p[i]));
1308         }
1309         TRACE(TRACE_MPI, "%s num_sges = %d, j = %d, k = %d",
1310                         ioc->name, sgl->num_sges, j, k);
1311         p = (u32 *)&req->SGL;
1312         for (i = 0; i < ((k != 0) ? priv->num_sge_target_assist : j); i++) {
1313 #if MPT_STM_64_BIT_DMA
1314         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x %08x",
1315                                 ioc->name, i * 12, le32_to_cpu(p[i*3]),
1316                                 le32_to_cpu(p[i*3+1]), le32_to_cpu(p[i*3+2]));
1317 #else
1318         _data = le32_to_cpu(p[i*2+1]);
1319         _buf = (u8 *)phys_to_virt(_data);
1320         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x,%x,%x,%x,%x,%p",
1321                         ioc->name, i * 8, le32_to_cpu(p[i*2]), le32_to_cpu(p[i*2+1]),
1322                         _buf[0], _buf[1], _buf[2], _buf[3], _buf);
1323 #endif
1324         }
1325         p = (u32 *)priv->hw->cmd_buf[index].chain_sge;
1326         for (i = 0; i < ((k != 0) ? (k - 1) * priv->num_sge_chain + j : 0); i++) {
1327 #if MPT_STM_64_BIT_DMA
1328         TRACE(TRACE_MPI, "%s chain sgl[%04x] = %08x %08x %08x",
1329                         ioc->name, i * 12, le32_to_cpu(p[i*3]),
1330                         le32_to_cpu(p[i*3+1]), le32_to_cpu(p[i*3+2]));
1331 #else
1332         _data = le32_to_cpu(p[i*2+1]);
1333         _buf = (u8 *)phys_to_virt(_data);
1334         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x,%x,%x,%x,%x,%p",
1335                         ioc->name, i * 8, le32_to_cpu(p[i*2]), le32_to_cpu(p[i*2+1]),
1336                         _buf[0], _buf[1], _buf[2], _buf[3], _buf);
1337 #endif
1338                 }
1339         }
1340 #endif
1341         res = 0;
1342         
1343         priv->io_state[index] |= IO_STATE_DATA_SENT;
1344         if (flags & TARGET_ASSIST_FLAGS_AUTO_STATUS)
1345                 priv->io_state[index] |= IO_STATE_STATUS_SENT;
1346
1347
1348         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
1349                 res =mpt_send_handshake_request(stm_context, _IOC_ID,
1350                                            ioc->req_sz, (u32 *)req _HS_SLEEP);
1351         } else {
1352                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
1353         }
1354
1355         TRACE_EXIT_RES(res);
1356         
1357         return res;     
1358 }
1359
1360 /* 
1361  * calling mpt_send_target_data
1362  *
1363  */
1364 static void 
1365 mpt_send_target_data(struct mpt_prm *prm, int flags)
1366 {
1367         MPT_STM_PRIV *priv;
1368         u32 reply_word;
1369         int index, lun, tag, length, offset;
1370         MPT_SGL *sgl;
1371         
1372         TRACE_ENTRY();
1373         priv = prm->tgt->priv;
1374         sgl = &priv->sgl;
1375         
1376         mpt_sge_to_sgl(prm, priv, sgl);
1377         
1378         reply_word = prm->cmd->CMD->reply_word;
1379         index = GET_IO_INDEX(reply_word);
1380
1381         lun = prm->cmd->CMD->lun;
1382         tag = prm->cmd->CMD->tag;
1383
1384         if (prm->data_direction == SCST_DATA_READ) {
1385                 flags |= TARGET_ASSIST_FLAGS_DATA_DIRECTION;
1386         }
1387         
1388         length = prm->bufflen;
1389         offset = 0;
1390 #if 0   
1391         TRACE_DBG("priv %p, reply_word %x, index %x, flags %x, lun %x, "
1392                   "tag %x, sgl %p, length %x, offset %x",
1393                   priv, reply_word, index, flags, lun, tag, 
1394                   sgl, length, offset);
1395 #endif  
1396         mpt_send_tgt_data(priv, reply_word, index, flags, lun, tag,
1397                         sgl, length, offset);
1398
1399         TRACE_EXIT();
1400         return;
1401 }
1402
1403 /*
1404  * this function checks if we need to handle REQUEST_SENSE on behalf of the 
1405  * target device.  If the sense wasn't able to be sent simultaneously 
1406  * with the status for the last command with a check condition, it needs 
1407  * to either get sent for a REQUEST_SENSE command or forgotten. 
1408  *
1409  * The pending_sense state and a buffer for holding sense is created for
1410  * each possible initiator.  The pending_sense state is used to tell if
1411  * sending sense failed and to track the progress of the following 
1412  * REQUEST_SENSE command.
1413  *
1414  * There are four values for the pending_sense state:
1415  * - STATUS_SENSE_IDLE: no caching of sense data is in progress
1416  * - STATUS_SENSE_ATTEMPT: an attempt is being made to send status and
1417  *   sense in the same bus transaction.
1418  * - STATUS_SENSE_NOT_SENT: the attempt to send simultanous status and
1419  *   sense failed.
1420  * - STATUS_SENSE_HANDLE_RQ: the next command from the initiator needs
1421  *   to be handled by the LSI driver if it is REQUEST_SENSE using cached
1422  *   sense data, otherwise the cached sense data is ignored and the
1423  *   command is sent to SCST.
1424  *
1425  * In stmapp_pending_sense, if pending_sense state for an initiator == 
1426  * SENSE_HANDLE_RQ, the incoming command is inspected.  If it is 
1427  * REQUEST_SENSE, the command is handled by the LSI driver without 
1428  * involving SCST.  The cached sense data from the immediately previous 
1429  * command is used.  This sense data was not sent along with the status 
1430  * for that command (see below).  If the command is not REQUEST_SENSE, 
1431  * the cached sense data is discarded and the command is sent to SCST 
1432  * for processing.
1433  *
1434  * In stm_send_target_status, sense data about to be sent is saved in a
1435  * buffer and the pending_sense state for that initiator is set to
1436  * MPT_STATUS_SENSE_ATTEMPT.  The sense and status are sent to the LSI
1437  * hardware.  
1438  *
1439  * If the LSI hardware determines that the sense and status could not be 
1440  * sent in one operation, stm_reply is called with state == STATUS_SENT 
1441  * and with IOCStatus of MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x6B).  
1442  * This condition only happens in the non-packetized SCSI operating mode.  
1443  * When this happens, the pending_sense state is advanced to 
1444  * MPT_STATUS_SENSE_NOT_SENT.
1445  *
1446  * In stm_tgt_reply, if io_state == STATUS_SENT:
1447  * - if pending_sense state == SENSE_ATTEMPT, the status and sense attempt was
1448  *   successful, so the pending_sense state is set to IDLE and the command
1449  *   is sent to SCST for completion.
1450  * - if pending_sense state == SENSE_NOT_SENT, the status and sense attempt
1451  *   failed.  The pending_sense state is advanced to SENSE_HANDLE_RQ and the
1452  *   current command is sent to SCST for completion.  The next command from
1453  *   this initiator will enter stmapp_pending_sense as described above.
1454  * - if pending_sense state == SENSE_HANDLE_RQ, the REQUEST_SENSE command
1455  *   handled alone by the LSI driver is done and resources need to be
1456  *   released.  pending_sense state is set to IDLE.
1457  * - if pending_sense state == SENSE_IDLE, a normal SCST command is done
1458  *   and is sent to SCST for completion.
1459  *
1460  * Because of this caching sense behaviour, we think we need to turn off
1461  * tagged command queueing.  The mpt_inquiry_no_tagged_commands function
1462  * does this by modifying INQUIRY data before sending it over the wire.
1463  */
1464 static int 
1465 stmapp_pending_sense(struct mpt_cmd *mpt_cmd)
1466 {
1467         int res = 0;
1468         MPT_STM_PRIV *priv;
1469         int index = 0;
1470         int init_index = 0;
1471         int flags = 0;
1472         SCSI_CMD *scsi_cmd = NULL;
1473         CMD *cmd;
1474         u8 *cdb;
1475         struct mpt_prm prm = { 0 };
1476         struct scst_cmd *scst_cmd;
1477         struct scatterlist sg;
1478
1479         TRACE_ENTRY();
1480
1481         priv = mpt_cmd->priv;
1482         if (IsScsi(priv)) {
1483                 index = GET_IO_INDEX(mpt_cmd->reply_word);
1484                 init_index = GET_INITIATOR_INDEX(mpt_cmd->reply_word);
1485                 if (atomic_read(&priv->pending_sense[init_index]) == 
1486                                 MPT_STATUS_SENSE_HANDLE_RQ) {
1487                         cmd = &priv->hw->cmd_buf[index];
1488                         scsi_cmd = (SCSI_CMD *)cmd->cmd;
1489                         cdb = scsi_cmd->CDB;
1490
1491                         if (cdb[0] == REQUEST_SENSE) {
1492                                 /* scst_cmd used as a container in stm_tgt_reply,
1493                                  * command doesn't actually go to SCST */
1494                                 scst_cmd = kmalloc(sizeof(struct scst_cmd), 
1495                                                 GFP_ATOMIC);
1496                                 TRACE_DBG("scst_cmd 0x%p", scst_cmd);
1497                                 if (scst_cmd != NULL) {
1498                                         cmd->reply_word = mpt_cmd->reply_word;
1499                                         if (cmd->reply_word & 
1500                                                 TARGET_MODE_REPLY_ALIAS_MASK) {
1501                                                 cmd->alias = (scsi_cmd->AliasID - 
1502                                                                 priv->port_id) & 15;
1503                                         } else {
1504                                                 cmd->alias = 0;
1505                                         }
1506                                         cmd->lun = get2bytes(scsi_cmd->LogicalUnitNumber, 
1507                                                         0);
1508                                         cmd->tag = scsi_cmd->Tag;
1509                                         mpt_cmd->CMD = cmd;
1510
1511                                         memset(scst_cmd, 0x00, 
1512                                                 sizeof(struct scst_cmd));
1513                                         scst_cmd->resp_data_len = -1;
1514                                         memcpy(scst_cmd->cdb, cdb, 
1515                                                         MPT_MAX_CDB_LEN);
1516                                         priv->scst_cmd[index] = scst_cmd;
1517                                         scst_cmd_set_tag(scst_cmd, cmd->tag);
1518                                         scst_cmd_set_tgt_priv(scst_cmd, mpt_cmd);
1519
1520                                         TRACE_BUFFER("CDB", cdb, MPT_MAX_CDB_LEN);
1521
1522                                         flags = TARGET_ASSIST_FLAGS_AUTO_STATUS;
1523                                         prm.cmd = mpt_cmd;
1524                                         /* smallest amount of data between
1525                                          * requested length, buffer size,
1526                                          * and cached length */
1527                                         prm.bufflen = min((size_t)cdb[4], 
1528                                                 (size_t)SCSI_SENSE_BUFFERSIZE);
1529                                         prm.bufflen = min(prm.bufflen, 
1530                                                 (size_t)(priv->pending_sense_buffer[init_index][7] 
1531                                                          + 8));
1532                                         sg.page = virt_to_page(priv->pending_sense_buffer[init_index]);
1533                                         sg.offset = offset_in_page(priv->pending_sense_buffer[init_index]);
1534                                         sg.length = prm.bufflen;
1535                                         prm.buffer = &sg;
1536                                         prm.use_sg = 1;
1537                                         prm.data_direction = SCST_DATA_READ;
1538                                         prm.tgt = priv->tgt->sess[init_index]->tgt;
1539                                         prm.cmd->state = MPT_STATE_DATA_OUT;
1540
1541                                         TRACE_DBG("%s: sending pending sense", 
1542                                                         priv->ioc->name);
1543                                         mpt_send_target_data(&prm, flags);
1544                                         res = 1;
1545                                 } else {
1546                                         /* we couldn't create a scst_cmd, so 
1547                                          * we can't do anything.  Send the
1548                                          * command to SCST. */
1549                                         atomic_set(&priv->pending_sense[init_index], 
1550                                                         MPT_STATUS_SENSE_IDLE);
1551                                 }
1552                         } else {
1553                                 /* next command immediately after check 
1554                                  * condition is not REQUEST_SENSE, so we can 
1555                                  * discard the cached sense and send the 
1556                                  * command to SCST. */
1557                                 atomic_set(&priv->pending_sense[init_index], 
1558                                                 MPT_STATUS_SENSE_IDLE);
1559                         }
1560                 } else {
1561                         /* we don't need to perform REQUEST_SENSE and can
1562                          * send the command to SCST */
1563                         atomic_set(&priv->pending_sense[init_index], 
1564                                         MPT_STATUS_SENSE_IDLE);
1565                 }
1566         }
1567
1568         TRACE_EXIT_RES(res);
1569         return res;
1570 }
1571
1572 /*
1573  * this function is equivalent to the SCSI queuecommand(). The target should
1574  * transmit the response data and the status in the struct scst_cmd. See
1575  * below for details. Must be defined.
1576  */
1577 static int 
1578 mpt_xmit_response(struct scst_cmd *scst_cmd)
1579 {
1580         int res = SCST_TGT_RES_SUCCESS;
1581         struct mpt_sess *sess;
1582         struct mpt_prm prm = { 0 };
1583         int resp_flags;
1584         //uint16_t full_req_cnt;
1585         //int data_sense_flag = 0;
1586
1587         TRACE_ENTRY();
1588         prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1589         sess = (struct mpt_sess *)
1590                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
1591         
1592         prm.sg = NULL;
1593         prm.bufflen = scst_cmd_get_resp_data_len(scst_cmd);
1594         prm.buffer = scst_cmd->sg;
1595         prm.use_sg = scst_cmd->sg_cnt;
1596         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
1597         prm.rq_result = scst_cmd_get_status(scst_cmd);
1598         prm.sense_buffer = scst_cmd_get_sense_buffer(scst_cmd);
1599         prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
1600         prm.tgt = sess->tgt;
1601         prm.seg_cnt = 0;
1602         resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
1603
1604         TRACE_DBG("rq_result=%x, resp_flags=%x, %x, %d", prm.rq_result, 
1605                         resp_flags, prm.bufflen, prm.sense_buffer_len);
1606         if (prm.rq_result != 0)
1607                 TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
1608
1609         if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) {
1610                 /* ToDo, after it's done in SCST */
1611                 PRINT_ERROR(MYNAM ": SCST_TSC_FLAG_STATUS not set: "
1612                             "feature not implemented %p", scst_cmd);
1613                 res = SCST_TGT_RES_FATAL_ERROR;
1614                 goto out_tgt_free;
1615         }
1616         
1617         if (test_bit(MPT_SESS_SHUTDOWN, &sess->sess_flags)) {
1618                 TRACE_DBG("cmd %p while session %p is shutting down",
1619                           prm.cmd, sess);
1620                 res = SCST_TGT_RES_SUCCESS;
1621                 goto out_tgt_free;
1622         }
1623         
1624         if (SCST_SENSE_VALID(prm.sense_buffer)) {
1625                 mpt_set_sense_info(prm.tgt->priv, prm.cmd->CMD, 
1626                                 prm.sense_buffer_len, prm.sense_buffer);
1627         }
1628
1629         if (scst_cmd_get_resp_data_len(scst_cmd) > 0) {
1630                 int flags = 0;
1631                 if (prm.rq_result == 0) {
1632                         flags |= TARGET_ASSIST_FLAGS_AUTO_STATUS;
1633                 }
1634                 if (scst_get_may_need_dma_sync(scst_cmd)) {
1635                         dma_sync_sg(&(prm.tgt->priv->ioc->pcidev->dev),
1636                                 scst_cmd->sg, scst_cmd->sg_cnt,
1637                                 scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
1638                 }
1639                 mpt_send_target_data(&prm, flags);
1640                 
1641                 if (prm.rq_result == 0) {
1642                         goto out;
1643                 }
1644         }
1645         {
1646                 int flags = 0;
1647                 u32 reply_word = prm.cmd->CMD->reply_word;
1648                 int index = GET_IO_INDEX(reply_word);
1649                 int lun = prm.cmd->CMD->lun;
1650                 int tag = prm.cmd->CMD->tag;
1651                 MPT_STM_PRIV *priv = prm.tgt->priv;
1652
1653                 if (prm.rq_result == 0) {
1654                         flags |= TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS;
1655                 }
1656
1657                 flags |= TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
1658                 priv->io_state[index] |= IO_STATE_AUTO_REPOST;
1659
1660                 TRACE_DBG("scst cmd %p, index %d, flags %d",
1661                                 scst_cmd, index, flags);
1662
1663                 stm_send_target_status(priv, reply_word, index, 
1664                                 flags, lun, tag);
1665         }
1666
1667  out:
1668         TRACE_EXIT_RES(res);
1669         
1670         return res;
1671
1672  out_tgt_free:
1673         scst_tgt_cmd_done(scst_cmd);
1674         goto out;
1675 }
1676
1677 /*
1678  * modifiy the response for an INQUIRY command to turn off
1679  * support for tagged command queuing if we're on a SCSI bus.
1680  * It's doubtful that caching sense data will work correctly
1681  * if tagging is enabled.
1682  */
1683 static void
1684 mpt_inquiry_no_tagged_commands(MPT_STM_PRIV *priv, struct scst_cmd *scst_cmd)
1685 {
1686         int32_t length;
1687         uint8_t *address;
1688
1689         TRACE_ENTRY();
1690
1691         /* 
1692          * only modify INQUIRY if we're on a SCSI bus,
1693          * and we are handling a standard INQUIRY command
1694          * (EVPD = 0)
1695          */
1696         if (IsScsi(priv) && (scst_cmd->cdb[0] == INQUIRY) && 
1697                         !(scst_cmd->cdb[1] & 0x1)) {
1698                 sBUG_ON(scst_cmd->sg_cnt == 0);
1699                 length = scst_get_buf_first(scst_cmd, &address);
1700                 if (length >= 8) {
1701                         TRACE_DBG("clearing BQUE + CMDQUE 0x%p", address);
1702                         address[6] &= ~0x80; /* turn off BQUE */
1703                         address[7] &= ~0x02; /* turn off CMDQUE */
1704                 }
1705                 scst_put_buf(scst_cmd, address);
1706         }
1707
1708         TRACE_EXIT();
1709 }
1710
1711 /*
1712  * this function 
1713  * informs the driver that data buffer corresponding to the said command
1714  * have now been allocated and it is OK to receive data for this command.
1715  * This function is necessary because a SCSI target does not have any
1716  * control over the commands it receives. Most lower-level protocols have a
1717  * corresponding function which informs the initiator that buffers have
1718  * been allocated e.g., XFER_RDY in Fibre Channel. After the data is
1719  * actually received the low-level driver should call scst_rx_data()
1720  * in order to continue processing this command. Returns one of the
1721  * SCST_TGT_RES_* constants, described below. Pay attention to
1722  * "atomic" attribute of the command, which can be get via
1723  * scst_cmd_get_atomic(): it is true if the function called in the
1724  * atomic (non-sleeping) context. Must be defined.
1725  */
1726 static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd)
1727 {
1728         int res = SCST_TGT_RES_SUCCESS;
1729         struct mpt_sess *sess;
1730         /*unsigned long flags = 0;*/
1731         struct mpt_prm prm = { 0 };
1732
1733         TRACE_ENTRY();
1734         prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1735         sess = (struct mpt_sess *)
1736                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
1737         mpt_inquiry_no_tagged_commands(sess->tgt->priv, scst_cmd);
1738
1739         prm.sg = (struct scatterlist *)NULL;
1740         prm.bufflen = scst_cmd->bufflen;
1741         prm.buffer = scst_cmd->sg;
1742         prm.use_sg = scst_cmd->sg_cnt;
1743         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
1744         prm.tgt = sess->tgt;
1745         
1746         if (test_bit(MPT_SESS_SHUTDOWN, &sess->sess_flags)) {
1747                 TRACE_DBG("cmd %p while session %p is shutting down",
1748                           prm.cmd, sess);
1749                 scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_FATAL,
1750                              SCST_CONTEXT_THREAD);
1751                 res = SCST_TGT_RES_SUCCESS;
1752                 goto out;
1753         }
1754         
1755         prm.cmd->state = MPT_STATE_NEED_DATA;
1756         
1757         mpt_send_target_data(&prm, 0);
1758         
1759  out:
1760         TRACE_EXIT_RES(res);
1761         
1762         return res;
1763 }
1764
1765 /*
1766  * this function
1767  * called to notify the driver that the command is about to be freed.
1768  * Necessary, because for aborted commands <bf/xmit_response()/ could not be
1769  * called. Could be used on IRQ context. Must be defined.
1770  */
1771 static void mpt_on_free_cmd(struct scst_cmd *scst_cmd)
1772 {
1773         struct mpt_cmd *cmd =
1774                 (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1775
1776         TRACE_ENTRY();
1777         
1778         TRACE_DBG("cmd %p, scst_cmd %p", cmd, scst_cmd);
1779
1780         scst_cmd_set_tgt_priv(scst_cmd, NULL);
1781
1782 #if 1
1783         memset(cmd, 0, sizeof(*cmd));
1784 #endif
1785         kfree(cmd);
1786
1787         TRACE_EXIT();
1788 }
1789
1790 /*
1791  * this function informs the driver that a received task management
1792  * function has been completed. Completion status could be get via
1793  * scst_mgmt_cmd_get_status(). No return value expected. Must be
1794  * defined, if the target supports task management functionality.
1795  */
1796 static void 
1797 mpt_task_mgmt_fn_done(struct scst_mgmt_cmd *mgmt_cmd)
1798 {
1799         TRACE_ENTRY();
1800         WARN_ON(1);
1801         TRACE_EXIT();
1802 }
1803
1804 static void
1805 mpt_local_task_mgmt(struct mpt_sess *sess, int task_mgmt, int lun)
1806 {
1807         struct mpt_cmd *cmd, *t;
1808         
1809         TRACE_ENTRY();
1810         switch (task_mgmt) {
1811         case IMM_NTFY_TARGET_RESET:
1812                 while (!list_empty(&sess->delayed_cmds)) {
1813                         cmd = list_entry(sess->delayed_cmds.next,
1814                                          typeof(*cmd), delayed_cmds_entry);
1815                         list_del(&cmd->delayed_cmds_entry);
1816                         kfree(cmd);
1817                 }
1818                 break;
1819
1820         case IMM_NTFY_LUN_RESET1:
1821         case IMM_NTFY_LUN_RESET2:
1822         case IMM_NTFY_CLEAR_TS:
1823         case IMM_NTFY_ABORT_TS:
1824                 list_for_each_entry_safe(cmd, t, &sess->delayed_cmds,
1825                                          delayed_cmds_entry)
1826                         {
1827                                 if (cmd->CMD->lun == lun) {
1828                                         list_del(&cmd->delayed_cmds_entry);
1829                                         kfree(cmd);
1830                                 }
1831                         }
1832                 break;
1833                 
1834         case IMM_NTFY_CLEAR_ACA:
1835         default:
1836                 break;
1837         }
1838         TRACE_EXIT();
1839 }
1840
1841 static int 
1842 mpt_handle_task_mgmt(MPT_STM_PRIV *priv, u32 reply_word,
1843                      int task_mgmt, int _lun)
1844 {
1845         int res = 0, rc = 0;
1846         struct mpt_mgmt_cmd *mcmd;
1847         struct mpt_tgt *tgt;
1848         struct mpt_sess *sess;
1849         int init_index;
1850         uint16_t lun = _lun;
1851
1852         TRACE_ENTRY();
1853         
1854         TRACE_DBG("task_mgmt %d", task_mgmt);
1855         tgt = priv->tgt;
1856         init_index = GET_INITIATOR_INDEX(reply_word);
1857         
1858         sess = tgt->sess[init_index];
1859         if (sess == NULL) {
1860                 TRACE(TRACE_MGMT, "mpt_scst(%s): task mgmt fn %p for "
1861                       "unexisting session", priv->ioc->name, tgt);
1862                 res = -EFAULT;
1863                 goto out;
1864         }
1865         
1866         if (test_bit(MPT_SESS_INITING, &sess->sess_flags)) {
1867                 TRACE(TRACE_MGMT, "mpt_scst(%s): task mgmt fn %p for "
1868                       "inited session", priv->ioc->name, tgt);
1869                 mpt_local_task_mgmt(sess, reply_word, task_mgmt);
1870                 res = -EFAULT;
1871                 goto out;
1872         }
1873         
1874         mcmd = kmalloc(sizeof(*mcmd), GFP_ATOMIC);
1875         TRACE_MEM("kmalloc(GFP_ATOMIC) for mcmd (%d): %p",
1876                   sizeof(*mcmd), mcmd);
1877         if (mcmd == NULL) {
1878                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1879                 res = -ENOMEM;
1880                 goto out;
1881         }
1882
1883         memset(mcmd, 0, sizeof(*mcmd));
1884         mcmd->sess = sess;
1885         mcmd->task_mgmt = task_mgmt;
1886         
1887         switch(task_mgmt) {
1888         case IMM_NTFY_CLEAR_ACA:
1889                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1890                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1891                                          (uint8_t *)&lun, sizeof(lun),
1892                                          SCST_ATOMIC, mcmd);
1893                 break;
1894         case IMM_NTFY_TARGET_RESET:
1895                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1896                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1897                                          (uint8_t *)&lun, sizeof(lun),
1898                                          SCST_ATOMIC, mcmd);
1899                 break;
1900         case IMM_NTFY_LUN_RESET1:
1901         case IMM_NTFY_LUN_RESET2:
1902                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1903                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1904                                          (uint8_t *)&lun, sizeof(lun),
1905                                          SCST_ATOMIC, mcmd);
1906                 break;
1907         case IMM_NTFY_CLEAR_TS:
1908                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1909                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1910                                          (uint8_t *)&lun, sizeof(lun),
1911                                          SCST_ATOMIC, mcmd);
1912                 break;
1913                 
1914         case IMM_NTFY_ABORT_TS:
1915                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1916                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1917                                          (uint8_t *)&lun, sizeof(lun),
1918                                          SCST_ATOMIC, mcmd);
1919                 break;
1920
1921         default:
1922                 PRINT_ERROR("mpt_scst(%s): Unknown task mgmt fn 0x%x",
1923                             priv->ioc->name, task_mgmt);
1924                 break;
1925         }
1926         if (rc != 0) {
1927                 PRINT_ERROR("mpt_scst(%s): scst_rx_mgmt_fn_lun() failed: %d",
1928                             priv->ioc->name, rc);
1929                 res = -EFAULT;
1930                 goto out_free;
1931         }
1932
1933  out:
1934         TRACE_EXIT_RES(res);
1935         return res;
1936
1937  out_free:
1938         TRACE_MEM("kmem_cache_free for mcmd %p", mcmd);
1939         kfree(mcmd);
1940         goto out;
1941 }
1942
1943
1944
1945 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1946 /*
1947  *  called when any target mode reply is received
1948  *  if mf_req is null, then this is a turbo reply; otherwise it's not
1949  */
1950 static int
1951 stm_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf_req, MPT_FRAME_HDR *mf_rep)
1952 {
1953     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
1954     MPIDefaultReply_t   *rep = (MPIDefaultReply_t *)mf_rep;
1955     int ioc_status;
1956
1957         TRACE_ENTRY();
1958         if (mf_req == NULL) {
1959                 TRACE_DBG("%s: got turbo reply, reply %x",
1960                                 ioc->name, CAST_PTR_TO_U32(mf_rep));
1961                 /*
1962                  *  this is a received SCSI command, so go handle it
1963                  */
1964                 stm_tgt_reply(ioc, CAST_PTR_TO_U32(mf_rep));
1965                 return 0;
1966         }
1967
1968 #if 0
1969     if (rep->Function == MPI_FUNCTION_EVENT_NOTIFICATION) {
1970         /*
1971          *  this is an event notification -- do nothing for now
1972          *  (this short-cuts the switch() below and avoids the printk)
1973          */
1974         return (0);
1975     }
1976 #endif
1977     ioc_status = le16_to_cpu(rep->IOCStatus);
1978
1979     TRACE_DBG("%s: request %p, reply %p (%02x), %d",
1980               ioc->name, mf_req, mf_rep, rep->Function, ioc_status);
1981     TRACE_DBG("%s: mf index = %d", ioc->name, MF_TO_INDEX(mf_req));
1982
1983         if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
1984                 TRACE_DBG("%s Function = %02x, IOCStatus = %04x, IOCLogInfo = %08x",
1985                                 ioc->name, rep->Function, ioc_status,
1986                                 le32_to_cpu(rep->IOCLogInfo));
1987         }
1988
1989     ioc_status &= MPI_IOCSTATUS_MASK;
1990     switch (rep->Function) {
1991         case MPI_FUNCTION_CONFIG:
1992             /*
1993              *  this signals that the config is done
1994              */
1995             priv->config_pending = 0;
1996             memcpy(&priv->config_rep, rep, sizeof(ConfigReply_t));
1997             /*
1998              *  don't free the message frame, since we're remembering it
1999              *  in priv->config_mf, and we'll be using it over and over
2000              */
2001             return (0);
2002
2003         case MPI_FUNCTION_PORT_ENABLE:
2004             /*
2005              *  this signals that the port enable is done
2006              */
2007             priv->port_enable_loginfo = le32_to_cpu(rep->IOCLogInfo);
2008             priv->port_enable_pending = 0;
2009             return (1);
2010
2011         case MPI_FUNCTION_TARGET_CMD_BUFFER_POST:
2012         case MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST:
2013             /*
2014              *  this is the response to a command buffer post; if status
2015              *  is success, then this just acknowledges the posting of a
2016              *  command buffer, so do nothing
2017              *
2018              *  we can also get here for High Priority I/O (such as getting
2019              *  a command while not being allowed to disconnect from the SCSI
2020              *  bus), and if we're shutting down
2021              */
2022                 if (ioc_status == MPI_IOCSTATUS_SUCCESS) {
2023                         TRACE_EXIT();
2024                         return 1;
2025                 }
2026                 if (priv->target_mode_abort_pending &&
2027                                 ioc_status == MPI_IOCSTATUS_TARGET_ABORTED) {
2028                         TRACE_EXIT();
2029                         return (0);
2030                 }
2031                 if (ioc_status == MPI_IOCSTATUS_TARGET_PRIORITY_IO) {
2032                         stm_tgt_reply_high_pri(ioc,
2033                                         (TargetCmdBufferPostErrorReply_t *)rep);
2034                         TRACE_EXIT();
2035                         return (0);
2036                 }
2037                 TRACE_DBG(":%s TargetCmdBufPostReq IOCStatus = %04x",
2038                                 ioc->name, ioc_status);
2039                 if (ioc_status == MPI_IOCSTATUS_INSUFFICIENT_RESOURCES) {
2040                         /*
2041                          *  this should never happen since we carefully count
2042                          *  our resources, but if it does, tolerate it -- don't
2043                          *  repost the errant command buffer, lest we create an
2044                          *  endless loop
2045                          */
2046                         WARN_ON(1);
2047                         return (0);
2048                 }
2049                 if (ioc_status == MPI_IOCSTATUS_TARGET_NO_CONNECTION) {
2050                         printk(KERN_ERR MYNAM 
2051                                         ": %s: Got MPI_IOCSTATUS_TARGET_NO_CONNECTION\n",
2052                                         ioc->name);
2053                         return (0);
2054                 }
2055                 if (rep->MsgLength > sizeof(*rep)/sizeof(u32)) {
2056                         TRACE_DBG("MsgLength is %d, %d", 
2057                                         rep->MsgLength, sizeof(*rep)/sizeof(u32));
2058                         WARN_ON(1);
2059                         /*
2060                          *  the TargetCmdBufferPostErrorReply and TargetErrorReply
2061                          *  structures are nearly identical; the exception is that
2062                          *  the former does not have a TransferCount field, while
2063                          *  the latter does; add one
2064                          */
2065                         ((TargetErrorReply_t *)rep)->TransferCount = 0;
2066                         stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2067                         return (0);
2068                 }
2069                 WARN_ON(1);
2070             return (1);
2071
2072         case MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST:
2073             /*
2074              *  this signals that the command buffer base post is done
2075              */
2076             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2077                 printk(KERN_ERR MYNAM ":%s TargetCmdBufPostBaseReq IOCStatus = %04x\n",
2078                        ioc->name, ioc_status);
2079             }
2080             return (1);
2081
2082         case MPI_FUNCTION_TARGET_ASSIST:
2083             /*
2084              *  this is the response to a target assist command; we should
2085              *  only get here if an error occurred
2086              *
2087              *  at this point we need to clean up the remains of the I/O
2088              *  and repost the command buffer
2089              */
2090             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2091                 printk(KERN_ERR MYNAM ":%s TargetAssistReq IOCStatus = %04x\n",
2092                        ioc->name, ioc_status);
2093             }
2094             stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2095             return (0);
2096
2097         case MPI_FUNCTION_TARGET_STATUS_SEND:
2098             /*
2099              *  this is the response to a target status send command; we should
2100              *  only get here if an error occurred
2101              *
2102              *  at this point we need to clean up the remains of the I/O
2103              *  and repost the command buffer
2104              */
2105             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2106                 /* if this is a MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
2107                  * and we're SCSI, only print if we're debugging and
2108                  * tracing.  This is a normal consequence of attempting
2109                  * to send sense data and status in the same 
2110                  * transaction.
2111                  */
2112                 if (IsScsi(priv) && 
2113                         (ioc_status == MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT)) {
2114                         TRACE_DBG(MYNAM ":%s TargetStatusSendReq IOCStatus = %04x\n",
2115                                 ioc->name, ioc_status);
2116                 } else {
2117                         printk(KERN_ERR MYNAM ":%s TargetStatusSendReq IOCStatus = %04x\n",
2118                                 ioc->name, ioc_status);
2119                 }
2120             }
2121             stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2122             return (0);
2123
2124         case MPI_FUNCTION_TARGET_MODE_ABORT: {
2125             TargetModeAbort_t           *req = (TargetModeAbort_t *)mf_req;
2126
2127             /*
2128              *  this signals that the target mode abort is done
2129              */
2130             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2131                 printk(KERN_ERR MYNAM ":%s TargetModeAbort IOCStatus = %04x\n",
2132                        ioc->name, ioc_status);
2133             }
2134             if (req->AbortType == TARGET_MODE_ABORT_TYPE_ALL_CMD_BUFFERS) {
2135                 priv->target_mode_abort_pending = 0;
2136             } else {
2137                 u32             reply_word;
2138                 int             index;
2139                 volatile int    *io_state;
2140
2141                 /*
2142                  *  a target mode abort has finished, so check to see if
2143                  *  the I/O was aborted, but there was no error reply for
2144                  *  that aborted I/O (this will be the case for I/Os that
2145                  *  have no outstanding target assist or target status send
2146                  *  at the time of the abort request) -- so pretend that
2147                  *  the error reply came in with a status indicating that
2148                  *  the I/O was aborted
2149                  */
2150                 reply_word = le32_to_cpu(req->ReplyWord);
2151                 index = GET_IO_INDEX(reply_word);
2152                 io_state = priv->io_state + index;
2153                 if ((*io_state & IO_STATE_ABORTED) &&
2154                     !(*io_state & IO_STATE_DATA_SENT) &&
2155                     !(*io_state & IO_STATE_STATUS_SENT)) {
2156                     stmapp_target_error(priv, reply_word, index,
2157                                         MPI_IOCSTATUS_TARGET_ABORTED, 0);
2158                 }
2159                 /*
2160                 *  see if we were trying to abort a target assist or target
2161                 *  status send, but the abort didn't work (if the abort had
2162                 *  worked, the flag we're checking would be clear) -- if so,
2163                 *  just clear the various SRR flags, and wait for the initiator
2164                 *  to retry the SRR
2165                 */
2166                 if (*io_state & IO_STATE_REQUEST_ABORTED) {
2167                     printk(KERN_ERR MYNAM ":%s index %d: io_state = %x\n",
2168                            ioc->name, index, *io_state);
2169                     printk(KERN_ERR MYNAM ":%s   request was not aborted\n",
2170                            ioc->name);
2171                     *io_state &= ~IO_STATE_REQUEST_ABORTED;
2172                     *io_state &= ~IO_STATE_REISSUE_REQUEST;
2173                     *io_state &= ~IO_STATE_ADJUST_OFFSET;
2174                     *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2175                     *io_state &= ~IO_STATE_REDO_COMMAND;
2176                 }
2177             }
2178                 TRACE_EXIT_RES(1);
2179             return (1);
2180         }
2181
2182         case MPI_FUNCTION_FC_LINK_SRVC_BUF_POST:
2183             /*
2184              *  if the length is that of a default reply, then this is the
2185              *  response to a link service buffer post -- do nothing except
2186              *  report errors (none are expected); otherwise this is a
2187              *  received ELS, so go handle it
2188              */
2189             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2190                 if (priv->link_serv_abort_pending &&
2191                     ioc_status == MPI_IOCSTATUS_FC_ABORTED) {
2192                     return (0);
2193                 }
2194                 printk(KERN_ERR MYNAM ":%s FcLinkServBufPostReq IOCStatus = %04x\n",
2195                        ioc->name, ioc_status);
2196             }
2197             if (rep->MsgLength > sizeof(*rep)/sizeof(u32)) {
2198                 stm_link_service_reply(ioc,
2199                                        (LinkServiceBufferPostReply_t *)rep);
2200                 return (0);
2201             }
2202             return (1);
2203
2204         case MPI_FUNCTION_FC_LINK_SRVC_RSP:
2205             /*
2206              *  this is the response to a link service send -- repost the
2207              *  link service command buffer
2208              */
2209             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2210                 printk(KERN_ERR MYNAM ":%s FcLinkServRspReq IOCStatus = %04x\n",
2211                        ioc->name, ioc_status);
2212             }
2213             stm_link_service_rsp_reply(ioc,
2214                                        (LinkServiceRspRequest_t *)mf_req,
2215                                        (LinkServiceRspReply_t *)mf_rep);
2216             return (1);
2217
2218         case MPI_FUNCTION_FC_ABORT:
2219             /*
2220              *  this signals that the target mode abort is done
2221              */
2222             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2223                 printk(KERN_ERR MYNAM ":%s FcAbort IOCStatus = %04x\n",
2224                        ioc->name, ioc_status);
2225             }
2226             priv->link_serv_abort_pending = 0;
2227             return (1);
2228
2229         case MPI_FUNCTION_FC_PRIMITIVE_SEND:
2230             /*
2231              *  this signals that the FC primitive send is done
2232              */
2233             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2234                 printk(KERN_ERR MYNAM ":%s FcPrimitiveSend IOCStatus = %04x\n",
2235                        ioc->name, ioc_status);
2236             }
2237             priv->fc_primitive_send_pending = 0;
2238             return (1);
2239
2240         case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
2241             /*
2242              *  this signals that the extended link service send is done
2243              */
2244             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2245                 printk(KERN_ERR MYNAM ":%s ExLinkServiceSend IOCStatus = %04x\n",
2246                        ioc->name, ioc_status);
2247             }
2248             priv->ex_link_service_send_pending = 0;
2249             return (1);
2250
2251         default:
2252             /*
2253              *  don't understand this reply, so dump to the screen
2254              */
2255             printk(KERN_ERR MYNAM ":%s got a reply (function %02x) that "
2256                    "I don't know what to do with\n", ioc->name, rep->Function);
2257 if(1)
2258 {
2259             u32 *p = (u32 *)mf_req;
2260             int i;
2261
2262             for (i = 0; i < 16; i++) {
2263                 printk("%s mf_req[%02x] = %08x\n",
2264                        ioc->name, i * 4, le32_to_cpu(p[i]));
2265             }
2266 }
2267 if(1)
2268 {
2269             u32 *p = (u32 *)mf_rep;
2270             int i;
2271
2272             for (i = 0; i < 16; i++) {
2273                 printk("%s mf_rep[%02x] = %08x\n",
2274                        ioc->name, i * 4, le32_to_cpu(p[i]));
2275             }
2276 }
2277             break;
2278     }
2279         TRACE_EXIT();
2280     return (0);
2281 }
2282
2283 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2284 static void
2285 stm_tgt_reply_high_pri(MPT_ADAPTER *ioc, TargetCmdBufferPostErrorReply_t *rep)
2286 {
2287         MPT_STM_PRIV    *priv = mpt_stm_priv[ioc->id];
2288         u32                     reply_word;
2289         int                     reason;
2290         int                     index;
2291
2292         TRACE_ENTRY();
2293         reply_word = le32_to_cpu(rep->ReplyWord);
2294         reason = rep->PriorityReason;
2295
2296         index = GET_IO_INDEX(reply_word);
2297
2298         TRACE_DBG("%s: target reply high priority", ioc->name);
2299         TRACE_DBG("%s: ReplyWord = %08x, PriorityReason = %02x",
2300                         ioc->name, reply_word, reason);
2301
2302         priv->io_state[index] |= IO_STATE_HIGH_PRIORITY;
2303         if (reason == PRIORITY_REASON_NO_DISCONNECT ||
2304                         reason == PRIORITY_REASON_SCSI_TASK_MANAGEMENT) {
2305                 stm_tgt_reply(ioc, reply_word);
2306                 goto out;       
2307         } 
2308
2309         WARN_ON(1);
2310         if (reason == PRIORITY_REASON_TARGET_BUSY) {
2311                 CMD             *cmd;
2312                 int             lun;
2313                 int             tag;
2314
2315                 priv->io_state[index] &= ~IO_STATE_POSTED;
2316                 cmd = &priv->hw->cmd_buf[index];
2317                 if (IsScsi(priv)) {
2318                         SCSI_CMD        *scsi_cmd = (SCSI_CMD *)cmd->cmd;
2319
2320                         lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
2321                         tag = scsi_cmd->Tag;
2322                 } else if (IsSas(priv)) {
2323                         SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
2324
2325                         lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
2326                         tag = ssp_cmd->InitiatorTag;
2327                 } else {
2328                         FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
2329
2330                         lun = get2bytes(fcp_cmd->FcpLun, 0);
2331                         tag = 0;
2332                 }
2333                 memset(cmd->rsp, 0, sizeof(cmd->rsp));
2334                 stmapp_set_status(priv, cmd, STS_TASK_SET_FULL);
2335                 stm_send_target_status(priv, reply_word, index, 0, lun, tag);
2336         } else {
2337                 stmapp_target_error(priv, reply_word, index,
2338                                 MPI_IOCSTATUS_TARGET_PRIORITY_IO, reason);
2339         }
2340 out:
2341         TRACE_EXIT();
2342 }
2343
2344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2345 static void
2346 stm_target_reply_error(MPT_ADAPTER *ioc,
2347                        TargetErrorReply_t *rep)
2348 {
2349     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2350     u32                 reply_word;
2351     int                 index;
2352     int                 status;
2353     int                 reason;
2354     volatile int        *io_state;
2355
2356         TRACE_ENTRY();
2357     reply_word = le32_to_cpu(rep->ReplyWord);
2358     status = le16_to_cpu(rep->IOCStatus) & MPI_IOCSTATUS_MASK;
2359
2360     index = GET_IO_INDEX(reply_word);
2361
2362     io_state = priv->io_state + index;
2363
2364         if (status == MPI_IOCSTATUS_TARGET_PRIORITY_IO) {
2365                 reason = rep->PriorityReason;
2366                 *io_state |= IO_STATE_HIGH_PRIORITY;
2367         } else {
2368                 reason = 0;
2369         }
2370
2371     TRACE_DBG("%s: target reply error", ioc->name);
2372     TRACE_DBG("%s: ReplyWord = %08x, IOCStatus = %04x",
2373            ioc->name, reply_word, status);
2374
2375         if (*io_state & IO_STATE_REQUEST_ABORTED) {
2376                 TRACE_DBG("%s: index %d: io_state = %x",
2377                                 ioc->name, index, *io_state);
2378                 TRACE_DBG("%s:   request was aborted", ioc->name);
2379                 *io_state &= ~IO_STATE_REQUEST_ABORTED;
2380                 if (*io_state & IO_STATE_REISSUE_REQUEST) {
2381                         *io_state &= ~IO_STATE_REISSUE_REQUEST;
2382                         TRACE_DBG("%s:   being reissued", ioc->name);
2383                         if (*io_state & IO_STATE_ADJUST_OFFSET) {
2384                                 *io_state &= ~IO_STATE_ADJUST_OFFSET;
2385                                 stmapp_srr_adjust_offset(priv, index);
2386                         }
2387                         if (*io_state & IO_STATE_CONVERT_TA_TO_TSS) {
2388                                 *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2389                                 stmapp_srr_convert_ta_to_tss(priv, index);
2390                                 goto out;
2391                         }
2392                         if (*io_state & IO_STATE_REDO_COMMAND) {
2393                                 *io_state &= ~IO_STATE_REDO_COMMAND;
2394                                 *io_state &= ~IO_STATE_DATA_SENT;
2395                                 *io_state &= ~IO_STATE_STATUS_SENT;
2396                                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
2397                                 stmapp_tgt_command(priv, reply_word);
2398                                 goto out;
2399                         }
2400                         mpt_put_msg_frame(stm_context, _IOC_ID, priv->current_mf[index]);
2401                         goto out;
2402                 }
2403         }
2404
2405     stmapp_target_error(priv, reply_word, index, status, reason);
2406 out:
2407         TRACE_EXIT();
2408 }
2409
2410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2411 static void
2412 stm_target_cleanup(MPT_STM_PRIV *priv,
2413                    int index)
2414 {
2415     MPT_ADAPTER         *ioc = priv->ioc;
2416     volatile int        *io_state;
2417
2418         TRACE_ENTRY();
2419         io_state = priv->io_state + index;
2420         if (*io_state & (IO_STATE_DATA_SENT | IO_STATE_STATUS_SENT)) {
2421                 *io_state &= ~IO_STATE_DATA_SENT;
2422                 *io_state &= ~IO_STATE_STATUS_SENT;
2423                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
2424         }
2425         if (*io_state & IO_STATE_STATUS_DEFERRED) {
2426                 *io_state &= ~IO_STATE_STATUS_DEFERRED;
2427                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->status_deferred_mf[index]);
2428         }
2429         *io_state &= ~IO_STATE_REISSUE_REQUEST;
2430         *io_state &= ~IO_STATE_ADJUST_OFFSET;
2431         *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2432         *io_state &= ~IO_STATE_REDO_COMMAND;
2433         *io_state &= ~IO_STATE_REQUEST_ABORTED;
2434         *io_state &= ~IO_STATE_INCOMPLETE;
2435         //  *io_state &= ~IO_STATE_AUTO_REPOST;
2436         *io_state &= ~IO_STATE_ABORTED;
2437         *io_state &= ~IO_STATE_POSTED;
2438         if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
2439                 *io_state = IO_STATE_POSTED;
2440         } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
2441                 stm_cmd_buf_post(priv, index);
2442         }
2443         TRACE_EXIT();
2444 }
2445
2446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2447 static int
2448 stm_event_process(MPT_ADAPTER *ioc,
2449                   EventNotificationReply_t *rep)
2450 {
2451     MPT_STM_PRIV                *priv = mpt_stm_priv[ioc->id];
2452     EventDataScsi_t             *scsi_data;
2453     EventDataLinkStatus_t       *link_status_data;
2454     EventDataLoopState_t        *loop_state_data;
2455     EventDataLogout_t           *logout_data;
2456     EventDataSasPhyLinkStatus_t *sas_phy_link_status_data;
2457     int                         id;
2458     int                         i;
2459     int                         ioc_status;
2460     int                         event;
2461     int                         rate;
2462
2463         TRACE_ENTRY();
2464     if (priv == NULL) {
2465                 return (1);
2466         }
2467
2468     ioc_status = le16_to_cpu(rep->IOCStatus);
2469     event = le32_to_cpu(rep->Event);
2470
2471         if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
2472                 printk("%s Event = %x, IOCLogInfo = %08x\n",
2473                                 ioc->name, event, le32_to_cpu(rep->IOCLogInfo));
2474         }
2475
2476     switch (event) {
2477         case MPI_EVENT_NONE:
2478         case MPI_EVENT_LOG_DATA:
2479         case MPI_EVENT_STATE_CHANGE:
2480         case MPI_EVENT_UNIT_ATTENTION:
2481         case MPI_EVENT_EVENT_CHANGE:
2482         case MPI_EVENT_INTEGRATED_RAID:
2483         case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
2484         case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
2485         case MPI_EVENT_QUEUE_FULL:
2486         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2487         case MPI_EVENT_SAS_SES:
2488         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2489         case MPI_EVENT_SAS_DISCOVERY_ERROR:
2490             break;
2491
2492         case MPI_EVENT_RESCAN:
2493             printk("%s Rescan\n", ioc->name);
2494             break;
2495
2496         case MPI_EVENT_IOC_BUS_RESET:
2497             scsi_data = (EventDataScsi_t *)rep->Data;
2498             printk("%s IOC Bus Reset on port %d\n",
2499                    ioc->name, scsi_data->BusPort);
2500             break;
2501
2502         case MPI_EVENT_EXT_BUS_RESET:
2503             scsi_data = (EventDataScsi_t *)rep->Data;
2504             printk("%s Ext Bus Reset on port %d\n",
2505                    ioc->name, scsi_data->BusPort);
2506             /*
2507              * clear any pending sense flags on bus reset
2508              */
2509             if (IsScsi(priv)) {
2510                     for (i = 0; i < NUM_SCSI_DEVICES; i++) {
2511                             atomic_set(&priv->pending_sense[i], 
2512                                             MPT_STATUS_SENSE_IDLE);
2513                     }
2514             }
2515             break;
2516
2517         case MPI_EVENT_LINK_STATUS_CHANGE:
2518             link_status_data = (EventDataLinkStatus_t *)rep->Data;
2519             printk("%s Link is now %s\n",
2520                    ioc->name, link_status_data->State ? "Up" : "Down");
2521             break;
2522
2523         case MPI_EVENT_LOGOUT:
2524             logout_data = (EventDataLogout_t *)rep->Data;
2525             id = le32_to_cpu(logout_data->NPortID);
2526             break;
2527
2528         case MPI_EVENT_LOOP_STATE_CHANGE:
2529             loop_state_data = (EventDataLoopState_t *)rep->Data;
2530             if (loop_state_data->Type == MPI_EVENT_LOOP_STATE_CHANGE_LIP) {
2531                 printk("%s LIP Reset\n", ioc->name);
2532                 break;
2533             } /* fall-through */
2534
2535         case MPI_EVENT_SAS_PHY_LINK_STATUS:
2536             sas_phy_link_status_data = (EventDataSasPhyLinkStatus_t *)rep->Data;
2537             rate = (sas_phy_link_status_data->LinkRates &
2538                     MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
2539                      MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
2540             printk("%s Phy %d Handle %x is now %s\n",
2541                    ioc->name, sas_phy_link_status_data->PhyNum,
2542                    le16_to_cpu(sas_phy_link_status_data->DevHandle),
2543                    rate == MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN ? "offline" :
2544                    rate == MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED ? "disabled" :
2545                    rate == MPI_EVENT_SAS_PLS_LR_RATE_1_5 ? "online at 1.5 Gb" :
2546                    rate == MPI_EVENT_SAS_PLS_LR_RATE_3_0 ? "online at 3.0 Gb" :
2547                    "unknown");
2548             break;
2549
2550         default:
2551             printk("%s event = %d, ack = %d, length = %d\n",
2552                    ioc->name, le32_to_cpu(rep->Event),
2553                    rep->AckRequired, le16_to_cpu(rep->EventDataLength));
2554             for (i = 0; i < le16_to_cpu(rep->EventDataLength); i++) {
2555                 printk("%s data[%d] = %08x\n",
2556                        ioc->name, i, le32_to_cpu(rep->Data[i]));
2557             }
2558             break;
2559     }
2560
2561     if (event == MPI_EVENT_EXT_BUS_RESET) {
2562 #if 0
2563         if (IsScsi(priv)) {
2564             memset(priv->luns->drop, 0, sizeof(priv->luns->drop));
2565         }
2566 #endif
2567     }
2568         TRACE_EXIT();
2569
2570     return (1);
2571 }
2572
2573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2574 static int
2575 stm_reset_process(MPT_ADAPTER *ioc, int phase)
2576 {
2577     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2578     int                 i;
2579
2580         TRACE_ENTRY();
2581         if (priv == NULL)
2582                 return (1);
2583
2584         if (phase == MPT_IOC_PRE_RESET) {
2585                 printk(KERN_ERR MYNAM ":%s IOC will be reset\n",
2586                                 ioc->name);
2587                 priv->in_reset = 1;
2588                 priv->config_pending = 0;
2589                 for (i = 0; i < priv->num_cmd_buffers; i++)
2590                         priv->io_state[i] = 0;
2591         }
2592
2593         if (phase == MPT_IOC_POST_RESET) {
2594                 printk(KERN_ERR MYNAM ":%s IOC has been reset, restarting now\n",
2595                                 ioc->name);
2596                 mpt_stm_adapter_online(priv);
2597         }
2598
2599         TRACE_EXIT();
2600
2601     return (1);
2602 }
2603
2604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2605 static void
2606 stm_link_service_reply(MPT_ADAPTER *ioc, LinkServiceBufferPostReply_t *rep)
2607 {
2608     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2609     FC_ELS              *fc_els_buf;
2610     int                 index;
2611     int                 rctl;
2612     int                 type;
2613     int                 sid;
2614     int                 did;
2615     int                 command;
2616     int                 i;
2617     u32                 wwnnh;
2618     u32                 wwnnl;
2619     u32                 wwpnh;
2620     u32                 wwpnl;
2621     int                 ox_id;
2622     int                 rx_id;
2623     u32                 offset;
2624
2625         TRACE_ENTRY();
2626     index = le32_to_cpu(rep->TransactionContext);
2627     fc_els_buf = &priv->hw->fc_link_serv_buf[index];
2628
2629     rctl =
2630         (le32_to_cpu(rep->Rctl_Did) & MPI_FC_RCTL_MASK) >> MPI_FC_RCTL_SHIFT;
2631     type =
2632         (le32_to_cpu(rep->Type_Fctl) & MPI_FC_TYPE_MASK) >> MPI_FC_TYPE_SHIFT;
2633     sid =
2634         (le32_to_cpu(rep->Csctl_Sid) & MPI_FC_SID_MASK) >> MPI_FC_SID_SHIFT;
2635     did =
2636         (le32_to_cpu(rep->Rctl_Did) & MPI_FC_DID_MASK) >> MPI_FC_DID_SHIFT;
2637
2638     wwnnh = le32_to_cpu(rep->Wwn.NodeNameHigh);
2639     wwnnl = le32_to_cpu(rep->Wwn.NodeNameLow);
2640     wwpnh = le32_to_cpu(rep->Wwn.PortNameHigh);
2641     wwpnl = le32_to_cpu(rep->Wwn.PortNameLow);
2642
2643     ox_id = le16_to_cpu(rep->Oxid);
2644     rx_id = le16_to_cpu(rep->Rxid);
2645
2646     /*
2647      *  if this is a received PRLI/PRLO, respond by sending our own PRLI/PRLO
2648      */
2649     if (rctl == ELS && type == 0x01) {
2650         command = (be32_to_cpu(fc_els_buf->fc_els[0]) >> 24) & 0xff;
2651         switch (command) {
2652             case PRLI:
2653                 TRACE_DBG("%s: PRLI to %06x from %06x (wwn %08x%08x)",
2654                                 ioc->name, did, sid, wwpnh, wwpnl);
2655                 i = be32_to_cpu(fc_els_buf->fc_els[4]);
2656                 fc_els_buf->fc_els[0] = cpu_to_be32(0x02100014);
2657                 fc_els_buf->fc_els[1] = cpu_to_be32(0x08002100);
2658                 fc_els_buf->fc_els[2] = cpu_to_be32(0x00000000);
2659                 fc_els_buf->fc_els[3] = cpu_to_be32(0x00000000);
2660                 fc_els_buf->fc_els[4] = cpu_to_be32(0x00000012);
2661                 if (priv->fcp2_capable)
2662                     fc_els_buf->fc_els[4] |= cpu_to_be32(0x100);
2663                 priv->els_state[index] = PRLI;
2664                 stm_send_els(priv, rep, index, 20);
2665                 return;
2666
2667             case PRLO:
2668                 TRACE_DBG("%s: PRLO to %06x from %06x (wwn %08x%08x)",
2669                         ioc->name, did, sid, wwpnh, wwpnl);
2670                 fc_els_buf->fc_els[0] = cpu_to_be32(0x02100014);
2671                 fc_els_buf->fc_els[1] = cpu_to_be32(0x08000100);
2672                 fc_els_buf->fc_els[2] = cpu_to_be32(0x00000000);
2673                 fc_els_buf->fc_els[3] = cpu_to_be32(0x00000000);
2674                 fc_els_buf->fc_els[4] = cpu_to_be32(0x00000000);
2675                 priv->els_state[index] = PRLO;
2676                 stm_send_els(priv, rep, index, 20);
2677                 return;
2678
2679             case RSCN:
2680                 TRACE_DBG("%s: RSCN", ioc->name);
2681                 stm_link_serv_buf_post(priv, index);
2682                 return;
2683
2684             default:
2685                 TRACE_DBG("%s: ELS %02x to %06x from %06x (wwn %08x%08x)",
2686                         ioc->name, command, did, sid, wwpnh, wwpnl);
2687                 stm_link_serv_buf_post(priv, index);
2688                 return;
2689         }
2690     }
2691
2692     /*
2693      *  if this is a received ABTS, respond by aborting the I/O and then
2694      *  accepting it
2695      */
2696     if (rctl == ABTS && type == 0x00) {
2697         TRACE_DBG("%s: ABTS to %06x from %06x (wwn %08x%08x)",
2698                 ioc->name, did, sid, wwpnh, wwpnl);
2699         fc_els_buf->fc_els[0] = cpu_to_be32(0x00000000);
2700         fc_els_buf->fc_els[1] = cpu_to_be32((ox_id << 16) | (rx_id << 0));
2701         fc_els_buf->fc_els[2] = cpu_to_be32(0x0000ffff);
2702         rep->Rctl_Did += cpu_to_le32((BA_ACC - ABTS) << MPI_FC_RCTL_SHIFT);
2703         priv->els_state[index] = ABTS;
2704         stmapp_abts_process(priv, rx_id, rep, index);
2705         stm_send_els(priv, rep, index, 12);
2706         return;
2707     }
2708
2709     /*
2710      *  if this is a received SRR, respond by aborting any current TargetAssist
2711      *  or TargetStatusSend commands, accepting the SRR, and retransmitting the
2712      *  requested data or status
2713      */
2714     if (rctl == FC4LS && type == 0x08) {
2715         priv->els_state[index] = FC4LS;
2716         command = (be32_to_cpu(fc_els_buf->fc_els[0]) >> 24) & 0xff;
2717         switch (command) {
2718             case SRR:
2719                 TRACE_DBG("%s: SRR to %06x from %06x (wwn %08x%08x)",
2720                         ioc->name, did, sid, wwpnh, wwpnl);
2721                 rx_id = be32_to_cpu(fc_els_buf->fc_els[1]) & 0xffff;
2722                 /*
2723                  *  if the rx_id is out of range, reject this SRR with
2724                  *  "invalid OX_ID/RX_ID combination"
2725                  */
2726                 if (rx_id >= priv->num_cmd_buffers) {
2727                     fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2728                     fc_els_buf->fc_els[1] = cpu_to_be32(0x00090300);
2729                     stm_send_els(priv, rep, index, 8);
2730                     return;
2731                 }
2732                 i = (be32_to_cpu(fc_els_buf->fc_els[3]) >> 24) & 0xff;
2733                 /*
2734                  *  if the IU to retransmit is not a recognized IU, reject
2735                  *  this SRR with "logical error"
2736                  */
2737                 if (i != 1 && i != 5 && i != 7) {
2738                     fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2739                     fc_els_buf->fc_els[1] = cpu_to_be32(0x00030000);
2740                     stm_send_els(priv, rep, index, 8);
2741                     return;
2742                 }
2743                 offset = be32_to_cpu(fc_els_buf->fc_els[2]);
2744                 /*
2745                  *  go process this SRR further
2746                  *
2747                  *  make the call to stm_send_els when any request in progress
2748                  *  has been aborted
2749                  *
2750                  *  note that the address of the LinkServiceBufferPostReply
2751                  *  that's passed as a parameter to stmapp_abts_process CANNOT
2752                  *  BE REMEMBERED; its contents must be copied if the call to
2753                  *  stm_send_els will not be made synchronously
2754                  */
2755                 stmapp_srr_process(priv, rx_id, i, offset, rep, index);
2756                 return;
2757
2758             default:
2759                 TRACE_DBG("%s: FC4LS %02x to %06x from %06x (wwn %08x%08x)",
2760                         ioc->name, command, did, sid, wwpnh, wwpnl);
2761                 /*
2762                  *  the only FC4LS we recognize is SRR; all others get
2763                  *  rejected with "command not supported"
2764                  */
2765                 fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2766                 fc_els_buf->fc_els[1] = cpu_to_be32(0x000b0000);
2767                 stm_send_els(priv, rep, index, 8);
2768                 return;
2769         }
2770     }
2771
2772 #ifdef TRACING
2773         if(trace_mpi)
2774         {
2775                 u32 *p = (u32 *)rep;
2776                 int i;
2777
2778                 for (i = 0; i < 17; i++) {
2779                         TRACE(TRACE_MPI, "%s: fc_els[%02x] = %08x",
2780                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2781                 }
2782         }
2783         if(trace_mpi)
2784         {
2785                 u32 *p = (u32 *)fc_els_buf;
2786                 int i;
2787
2788                 for (i = 0; i < (int)le32_to_cpu(rep->TransferLength) / 4; i++) {
2789                         TRACE(TRACE_MPI, "%s: fc_els_buf[%02x] = %08x",
2790                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2791                 }
2792         }
2793 #endif
2794
2795     stm_link_serv_buf_post(priv, index);
2796         TRACE_EXIT();
2797 }
2798
2799 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2800 static void
2801 stm_link_service_rsp_reply(MPT_ADAPTER *ioc,
2802                            LinkServiceRspRequest_t *req,
2803                            LinkServiceRspReply_t *rep)
2804 {
2805     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2806     MPT_STM_SIMPLE      *sge_simple;
2807     int                 *p_index;
2808     int                 index;
2809     int                 sid;
2810     int                 did;
2811     int                 els;
2812     int                 init_index;
2813
2814         TRACE_ENTRY();
2815     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
2816     p_index = (int *)(sge_simple + 1);
2817     index = *p_index;
2818     els = priv->els_state[index];
2819
2820     sid = (le32_to_cpu(req->Csctl_Sid) & MPI_FC_SID_MASK) >> MPI_FC_SID_SHIFT;
2821     did = (le32_to_cpu(req->Rctl_Did) & MPI_FC_DID_MASK) >> MPI_FC_DID_SHIFT;
2822     init_index = le32_to_cpu(rep->InitiatorIndex);
2823     /*
2824      *  after our link service reponse has been sent, repost the link service
2825      *  buffer
2826      */
2827     priv->els_state[index] = 0;
2828     stm_link_serv_buf_post(priv, index);
2829         TRACE_EXIT();
2830 }
2831
2832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2833 static void
2834 stm_cmd_buf_post(MPT_STM_PRIV *priv, int index)
2835 {
2836     MPT_ADAPTER *ioc = priv->ioc;
2837     TargetCmdBufferPostRequest_t *req;
2838     dma_addr_t  dma_addr;
2839
2840         TRACE_ENTRY();
2841         if (priv->exiting) {
2842                 priv->io_state[index] |= IO_STATE_POSTED;
2843                 return;
2844         }
2845
2846         if (IsSas(priv)) {
2847                 stm_cmd_buf_post_list(priv, index);
2848                 return;
2849         }
2850
2851     /*
2852      *  get a free message frame, and post a command buffer
2853      */
2854     req = (TargetCmdBufferPostRequest_t *)mpt_msg_frame_alloc(ioc,index);
2855     memset(req, 0, sizeof(*req));
2856
2857 #ifdef CMD_BUFFER_POST_FLAGS_HIGH_PRIORITY
2858         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
2859                 req->BufferPostFlags = CMD_BUFFER_POST_FLAGS_HIGH_PRIORITY;
2860         }
2861 #else
2862         priv->io_state[index] &= ~IO_STATE_HIGH_PRIORITY;
2863 #endif
2864
2865     req->BufferCount = 1;
2866     req->Function = MPI_FUNCTION_TARGET_CMD_BUFFER_POST;
2867     req->BufferLength = sizeof(priv->hw->cmd_buf[index].cmd);
2868     req->Buffer[0].IoIndex = (u16)cpu_to_le16(index);
2869     dma_addr = priv->hw_dma +
2870         ((u8 *)priv->hw->cmd_buf[index].cmd - (u8 *)priv->hw);
2871     req->Buffer[0].u.PhysicalAddress64.Low = cpu_to_le32(dma_addr);
2872 #if MPT_STM_64_BIT_DMA
2873     req->Buffer[0].u.PhysicalAddress64.High = cpu_to_le32((u64)dma_addr>>32);
2874     req->BufferPostFlags = CMD_BUFFER_POST_FLAGS_64_BIT_ADDR;
2875 #endif
2876
2877     priv->io_state[index] |= IO_STATE_POSTED;
2878
2879 #ifdef TRACING
2880         if(trace_mpi) {
2881                 u32 *p = (u32 *)req;
2882                 int i;
2883
2884                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post %d", ioc->name, index);
2885                 for (i = 0; i < sizeof(*req) / 4; i++) {
2886                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
2887                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2888                 }
2889         }
2890 #endif
2891
2892         priv->current_mf[index] = NULL;
2893         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
2894                 priv->io_state[index] &= ~IO_STATE_HIGH_PRIORITY;
2895                 mpt_send_handshake_request(stm_context, _IOC_ID,
2896                                 sizeof(*req), (u32 *)req _HS_SLEEP);
2897         } else {
2898                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
2899         }
2900
2901         TRACE_EXIT();
2902 }
2903
2904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2905 static void
2906 stm_cmd_buf_post_base(MPT_STM_PRIV *priv,
2907                       int post_all)
2908 {
2909     MPT_ADAPTER                         *ioc = priv->ioc;
2910     TargetCmdBufferPostBaseRequest_t    *req;
2911     int                                 i;
2912     dma_addr_t                          dma_addr;
2913
2914         TRACE_ENTRY();
2915     req = (TargetCmdBufferPostBaseRequest_t *)mpt_msg_frame_alloc(ioc,-1);
2916     memset(req, 0, sizeof(*req));
2917
2918     if (post_all) {
2919         req->BufferPostFlags = CMD_BUFFER_POST_BASE_FLAGS_AUTO_POST_ALL;
2920     }
2921     req->Function = MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST;
2922     req->TotalCmdBuffers = (u16)priv->num_cmd_buffers;
2923     req->CmdBufferLength = sizeof(priv->hw->cmd_buf[0].cmd);
2924     req->NextCmdBufferOffset = sizeof(priv->hw->cmd_buf[0]);
2925     dma_addr = priv->hw_dma +
2926         ((u8 *)priv->hw->cmd_buf[0].cmd - (u8 *)priv->hw);
2927     req->BaseAddressLow = cpu_to_le32(dma_addr);
2928 #if MPT_STM_64_BIT_DMA
2929     req->BaseAddressHigh = cpu_to_le32((u64)dma_addr>>32);
2930 #endif
2931
2932     if (post_all) {
2933         for (i = 0; i < priv->num_cmd_buffers; i++) {
2934             priv->io_state[i] |= IO_STATE_POSTED;
2935         }
2936     }
2937
2938 #ifdef TRACING
2939         if(trace_mpi)
2940         {
2941                 u32 *p = (u32 *)req;
2942                 int i;
2943
2944                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post_base", ioc->name);
2945                 for (i = 0; i < sizeof(*req) / 4; i++) {
2946                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
2947                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2948                 }
2949         }
2950 #endif
2951
2952     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
2953
2954         TRACE_EXIT();
2955 }
2956
2957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2958 static void
2959 stm_cmd_buf_post_list(MPT_STM_PRIV *priv,
2960                       int index)
2961 {
2962     MPT_ADAPTER                         *ioc = priv->ioc;
2963     TargetCmdBufferPostListRequest_t    *req;
2964
2965         TRACE_ENTRY();
2966     req = (TargetCmdBufferPostListRequest_t *)mpt_msg_frame_alloc(ioc,index);
2967     memset(req, 0, sizeof(*req));
2968
2969     req->Function = MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST;
2970     req->CmdBufferCount = 1;
2971     req->IoIndex[0] = (u16)cpu_to_le16(index);
2972
2973     priv->io_state[index] |= IO_STATE_POSTED;
2974
2975 #ifdef TRACING
2976         if(trace_mpi)
2977         {
2978                 u32 *p = (u32 *)req;
2979                 int i;
2980
2981                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post_list %d", ioc->name, index);
2982                 for (i = 0; i < sizeof(*req) / 4; i++) {
2983                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
2984                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2985                 }
2986         }
2987 #endif
2988
2989         mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
2990         TRACE_EXIT();
2991 }
2992
2993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2994 static void
2995 stm_link_serv_buf_post(MPT_STM_PRIV *priv, int index)
2996 {
2997     MPT_ADAPTER                         *ioc = priv->ioc;
2998     LinkServiceBufferPostRequest_t      *req;
2999     SGETransaction32_t                  *sge_trans;
3000     MPT_STM_SIMPLE                      *sge_simple;
3001     dma_addr_t                          dma_addr;
3002
3003         TRACE_ENTRY();
3004     req = (LinkServiceBufferPostRequest_t *)mpt_msg_frame_alloc(ioc,index);
3005     memset(req, 0, sizeof(*req));
3006
3007     req->BufferCount = 1;
3008     req->Function = MPI_FUNCTION_FC_LINK_SRVC_BUF_POST;
3009     sge_trans = (SGETransaction32_t *)&req->SGL;
3010     sge_trans->ContextSize = 4;
3011     sge_trans->DetailsLength = 0;
3012     sge_trans->Flags = 0;
3013     sge_trans->TransactionContext[0] = cpu_to_le32(index);
3014     sge_simple = (MPT_STM_SIMPLE *)&sge_trans->TransactionDetails[0];
3015     sge_simple->FlagsLength = cpu_to_le32(sizeof(FC_ELS) |
3016         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3017                           MPI_SGE_FLAGS_LAST_ELEMENT |
3018                           MPI_SGE_FLAGS_END_OF_BUFFER |
3019                           MPI_SGE_FLAGS_END_OF_LIST |
3020                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3021                           MPI_SGE_FLAGS_HOST_TO_IOC));
3022     dma_addr = priv->hw_dma +
3023         ((u8 *)priv->hw->fc_link_serv_buf[index].fc_els - (u8 *)priv->hw);
3024     stm_set_dma_addr(sge_simple->Address, dma_addr);
3025
3026 #ifdef TRACING
3027         if(trace_mpi)
3028         {
3029                 u32 *p = (u32 *)req;
3030                 int i;
3031
3032                 TRACE(TRACE_MPI, "%s: stm_link_serv_buf_post %d", ioc->name, index);
3033                 for (i = 0; i < sizeof(*req) / 4; i++) {
3034                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3035                                         ioc->name, i * 4, le32_to_cpu(p[i]));
3036                 }
3037         }
3038 #endif
3039         priv->current_mf[index] = NULL;
3040     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3041         TRACE_EXIT();
3042 }
3043
3044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3045 static int
3046 stm_send_target_status(MPT_STM_PRIV *priv,
3047                        u32 reply_word, int index, int flags, int lun, int tag)
3048 {
3049     MPT_ADAPTER                 *ioc = priv->ioc;
3050     TargetStatusSendRequest_t   *req;
3051     MPT_STM_SIMPLE              *sge_simple;
3052     CMD                         *cmd;
3053     int                         length;
3054     int                         status;
3055     int                         init_index;
3056     dma_addr_t                  dma_addr;
3057     MPT_FRAME_HDR *mf = priv->current_mf[index];
3058
3059     TRACE_ENTRY();
3060     if (priv->io_state[index] & IO_STATE_DATA_SENT) {
3061                 priv->current_mf[index] = NULL;
3062         }
3063     req = (TargetStatusSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3064     memset(req, 0, sizeof(*req));
3065
3066     if (priv->exiting) {
3067         flags &= ~TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
3068         priv->io_state[index] &= ~IO_STATE_AUTO_REPOST;
3069     }
3070
3071     if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
3072         flags |= TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY;
3073         flags |= TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
3074         priv->io_state[index] |= IO_STATE_AUTO_REPOST;
3075     }
3076
3077     if (priv->fcp2_capable/* && priv->initiators != NULL*/) {
3078         init_index = GET_INITIATOR_INDEX(reply_word);
3079         /*init = priv->initiators[init_index];
3080         if (init != NULL && init->confirm_capable) {
3081             flags |= TARGET_STATUS_SEND_FLAGS_CONFIRMED;
3082         }*/
3083     }
3084
3085     cmd = &priv->hw->cmd_buf[index];
3086
3087     if (flags & TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS) {
3088         length = 0;
3089         req->StatusCode = 0;
3090     } else {
3091         length = 0;
3092         if (IsScsi(priv)) {
3093             SCSI_RSP    *rsp = (SCSI_RSP *)cmd->rsp;
3094             size_t sense_size;
3095
3096             length += sizeof(*rsp);
3097             length -= sizeof(rsp->SenseData);
3098             status = rsp->Status;
3099             if (rsp->Valid & SCSI_SENSE_LEN_VALID) {
3100                 length += be32_to_cpu(rsp->SenseDataListLength);
3101                 init_index = GET_INITIATOR_INDEX(reply_word);
3102                 /*
3103                  *  try to avoid a SCSI firmware bug by not using Auto Repost
3104                  *  here, unless required (High Priority requires it)
3105                  */
3106                 if (!(priv->io_state[index] & IO_STATE_HIGH_PRIORITY)) {
3107                     flags &= ~TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
3108                     priv->io_state[index] &= ~IO_STATE_AUTO_REPOST;
3109                 }
3110                 /*
3111                  * cache sense buffer so we can send it on the next
3112                  * REQUEST SENSE command if the IOC can't send the
3113                  * status and sense simultaneously (generating 
3114                  * MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT IOCStatus)
3115                  */
3116                 sense_size = min(sizeof(rsp->SenseData), 
3117                                        (size_t)SCSI_SENSE_BUFFERSIZE);
3118                 TRACE_DBG("caching %d bytes pending sense", sense_size);
3119                 memcpy(priv->pending_sense_buffer[init_index], 
3120                                 rsp->SenseData, sense_size);
3121                 TRACE_BUFFER("priv->pending_sense_buffer", 
3122                                 priv->pending_sense_buffer[init_index], 
3123                                 sense_size);
3124                 atomic_set(&priv->pending_sense[init_index], 
3125                                 MPT_STATUS_SENSE_ATTEMPT);
3126             }
3127             if (rsp->Valid & SCSI_RSP_LEN_VALID) {
3128                 length += be32_to_cpu(rsp->PktFailuresListLength);
3129             }
3130         } else if (IsSas(priv)) {
3131             SSP_RSP     *rsp = (SSP_RSP *)cmd->rsp;
3132
3133             length += sizeof(*rsp);
3134             length -= sizeof(rsp->ResponseSenseData);
3135             status = rsp->Status;
3136             if (rsp->DataPres & SSP_SENSE_LEN_VALID) {
3137                 length += be32_to_cpu(rsp->SenseDataLength);
3138             }
3139             if (rsp->DataPres & SSP_RSP_LEN_VALID) {
3140                 length += be32_to_cpu(rsp->ResponseDataLength);
3141             }
3142         } else {
3143             FCP_RSP     *rsp = (FCP_RSP *)cmd->rsp;
3144
3145             length += sizeof(*rsp);
3146             length -= sizeof(rsp->FcpSenseData) + sizeof(rsp->FcpResponseData);
3147             status = rsp->FcpStatus;
3148             if (flags & TARGET_STATUS_SEND_FLAGS_CONFIRMED) {
3149                 rsp->FcpFlags |= FCP_REQUEST_CONFIRM;
3150             }
3151             if (rsp->FcpFlags & FCP_SENSE_LEN_VALID) {
3152                 length += be32_to_cpu(rsp->FcpSenseLength);
3153             }
3154             if (rsp->FcpFlags & FCP_RSP_LEN_VALID) {
3155                 length += be32_to_cpu(rsp->FcpResponseLength);
3156                 /* FCP_RSP_LEN_VALID will only be set for Task Mgmt responses */
3157                 /* and Task Mgmt responses can't be confirmed */
3158                 rsp->FcpFlags &= ~FCP_REQUEST_CONFIRM;
3159                 flags &= ~TARGET_STATUS_SEND_FLAGS_CONFIRMED;
3160             }
3161         }
3162         req->StatusCode = (u8)status;
3163     }
3164
3165     req->StatusFlags = (u8)flags;
3166     req->Function = MPI_FUNCTION_TARGET_STATUS_SEND;
3167     req->QueueTag = (u16)tag;
3168     req->ReplyWord = cpu_to_le32(reply_word);
3169     req->LUN[0] = (u8)(lun >> 8);
3170     req->LUN[1] = (u8)lun;
3171     if (length != 0) {
3172         sge_simple = (MPT_STM_SIMPLE *)&req->StatusDataSGE;
3173         sge_simple->FlagsLength = cpu_to_le32(length |
3174             MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3175                               MPI_SGE_FLAGS_LAST_ELEMENT |
3176                               MPI_SGE_FLAGS_END_OF_BUFFER |
3177                               MPI_SGE_FLAGS_END_OF_LIST |
3178                               MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3179                               MPI_SGE_FLAGS_HOST_TO_IOC));
3180         dma_addr = priv->hw_dma +
3181             ((u8 *)priv->hw->cmd_buf[index].rsp - (u8 *)priv->hw);
3182         stm_set_dma_addr(sge_simple->Address, dma_addr);
3183     }
3184
3185     /*
3186      *  there's a limitation here -- if target data is outstanding, we must
3187      *  wait for it to finish before we send the target status
3188      */
3189     if (priv->io_state[index] & IO_STATE_DATA_SENT) {
3190             priv->current_mf[index] = mf;
3191             priv->status_deferred_mf[index] = (MPT_FRAME_HDR *)req;
3192             priv->io_state[index] |= IO_STATE_STATUS_DEFERRED;
3193             TRACE_EXIT_RES(1);
3194             return (1);
3195     }
3196     priv->io_state[index] |= IO_STATE_STATUS_SENT;
3197
3198 #ifdef TRACING
3199     if(trace_mpi)
3200     {
3201             u32 *p = (u32 *)req;
3202             int i;
3203
3204             TRACE(TRACE_MPI, "%s: stm_send_target_status %d",
3205                             ioc->name, index);
3206             for (i = 0; i < sizeof(*req) / 4; i++) {
3207                     TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3208                                     ioc->name, i * 4, le32_to_cpu(p[i]));
3209             }
3210     }
3211 #endif
3212
3213     if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
3214             mpt_send_handshake_request(stm_context, _IOC_ID,
3215                             sizeof(*req), (u32 *)req _HS_SLEEP);
3216     } else {
3217             mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3218     }
3219     TRACE_EXIT_RES(1);
3220     return (1);
3221 }
3222
3223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3224 static void
3225 stm_send_els(MPT_STM_PRIV *priv,
3226              LinkServiceBufferPostReply_t *rep, int index, int length)
3227 {
3228     MPT_ADAPTER                 *ioc = priv->ioc;
3229     LinkServiceRspRequest_t     *req;
3230     MPT_STM_SIMPLE              *sge_simple;
3231     int                         *p_index;
3232     dma_addr_t                  dma_addr;
3233
3234         TRACE_ENTRY();
3235     req = (LinkServiceRspRequest_t *)mpt_msg_frame_alloc(ioc,index);
3236     memset(req, 0, sizeof(*req));
3237
3238     req->RspLength = (u8)length;
3239     req->Function = MPI_FUNCTION_FC_LINK_SRVC_RSP;
3240     memcpy((u8 *)req + 0x0c, (u8 *)rep + 0x1c, 24);
3241     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3242     sge_simple->FlagsLength = cpu_to_le32(length |
3243         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3244                           MPI_SGE_FLAGS_LAST_ELEMENT |
3245                           MPI_SGE_FLAGS_END_OF_BUFFER |
3246                           MPI_SGE_FLAGS_END_OF_LIST |
3247                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3248                           MPI_SGE_FLAGS_HOST_TO_IOC));
3249     dma_addr = priv->hw_dma +
3250         ((u8 *)priv->hw->fc_link_serv_buf[index].fc_els - (u8 *)priv->hw);
3251     stm_set_dma_addr(sge_simple->Address, dma_addr);
3252     p_index = (int *)(sge_simple + 1);
3253     *p_index = index;
3254
3255 #ifdef TRACING
3256         if(trace_mpi)
3257         {
3258                 u32 *p = (u32 *)req;
3259                 int i;
3260
3261                 TRACE(TRACE_MPI, "%s: stm_send_els %d", ioc->name, index);
3262                 for (i = 0; i < sizeof(*req) / 4; i++) {
3263                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x", 
3264                                         ioc->name, i * 4, le32_to_cpu(p[i]));
3265                 }
3266         }
3267 #endif
3268         priv->current_mf[index] = NULL;
3269     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3270         TRACE_EXIT();
3271 }
3272
3273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3274 static int
3275 stm_port_enable(MPT_STM_PRIV *priv)
3276 {
3277     MPT_ADAPTER         *ioc = priv->ioc;
3278     PortEnable_t        *req;
3279         int ret;
3280
3281         TRACE_ENTRY();
3282     req = (PortEnable_t *)mpt_msg_frame_alloc(ioc,-1);
3283     memset(req, 0, sizeof(*req));
3284
3285     req->Function = MPI_FUNCTION_PORT_ENABLE;
3286
3287     priv->port_enable_pending = 1;
3288
3289     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3290
3291     ret = stm_wait_for(priv, &priv->port_enable_pending, 60, NO_SLEEP);
3292
3293         TRACE_EXIT_RES(ret);
3294
3295         return ret;
3296 }
3297
3298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3299 static int
3300 stm_target_mode_abort_command(MPT_STM_PRIV *priv,
3301                               u32 reply_word, int index)
3302 {
3303     MPT_ADAPTER         *ioc = priv->ioc;
3304     TargetModeAbort_t   *req;
3305
3306         TRACE_ENTRY();
3307     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,index);
3308     memset(req, 0, sizeof(*req));
3309
3310     req->AbortType = TARGET_MODE_ABORT_TYPE_EXACT_IO;
3311     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3312     req->ReplyWord = cpu_to_le32(reply_word);
3313
3314     priv->io_state[index] |= IO_STATE_ABORTED;
3315
3316         if (IsScsi(priv)) {
3317                 mpt_send_handshake_request(stm_context, _IOC_ID,
3318                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3319         } else {
3320                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3321         }
3322         TRACE_EXIT();
3323
3324     return (0);
3325 }
3326
3327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3328 static int
3329 stm_target_mode_abort_request(MPT_STM_PRIV *priv,
3330                               u32 reply_word,
3331                               u32 msg_context,
3332                               int index)
3333 {
3334     MPT_ADAPTER         *ioc = priv->ioc;
3335     TargetModeAbort_t   *req;
3336
3337         TRACE_ENTRY();
3338     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,index);
3339     memset(req, 0, sizeof(*req));
3340
3341     req->AbortType = TARGET_MODE_ABORT_TYPE_EXACT_IO_REQUEST;
3342     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3343     req->ReplyWord = cpu_to_le32(reply_word);
3344     req->MsgContextToAbort = cpu_to_le32(msg_context);
3345
3346     priv->io_state[index] |= IO_STATE_REQUEST_ABORTED;
3347
3348         if (IsScsi(priv)) {
3349                 mpt_send_handshake_request(stm_context, _IOC_ID,
3350                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3351         } else {
3352                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3353         }
3354         TRACE_EXIT();
3355
3356     return (0);
3357 }
3358
3359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3360 static int
3361 stm_target_mode_abort_all(MPT_STM_PRIV *priv)
3362 {
3363     MPT_ADAPTER         *ioc = priv->ioc;
3364     TargetModeAbort_t   *req;
3365         int ret;
3366         TRACE_ENTRY();
3367
3368     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,-1);
3369     memset(req, 0, sizeof(*req));
3370
3371     req->AbortType = TARGET_MODE_ABORT_TYPE_ALL_CMD_BUFFERS;
3372     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3373
3374     priv->target_mode_abort_pending = 1;
3375
3376         if (IsScsi(priv)) {
3377                 mpt_send_handshake_request(stm_context, _IOC_ID,
3378                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3379         } else {
3380                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3381         }
3382
3383     ret = stm_wait_for(priv, &priv->target_mode_abort_pending, 60, NO_SLEEP);
3384         TRACE_EXIT_RES(ret);
3385
3386         return ret;
3387 }
3388
3389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3390 static int
3391 stm_target_mode_abort(MPT_STM_PRIV *priv)
3392 {
3393 #ifdef DEBUG
3394     MPT_ADAPTER         *ioc = priv->ioc;
3395 #endif
3396     int                 i;
3397     int                 n;
3398
3399         TRACE_ENTRY();
3400         while (1) {
3401                 n = 0;
3402                 for (i = 0; i< priv->num_cmd_buffers; i++) {
3403                         if (priv->io_state[i] & IO_STATE_AUTO_REPOST) {
3404                                 n++;
3405                         }
3406                 }
3407
3408                 if (n == 0)
3409                         break;
3410
3411                 TRACE_DBG("%s: %d out of %d commands being auto-reposted, waiting...",
3412                                 ioc->name, n, priv->num_cmd_buffers);
3413                 stm_wait(priv, 10, CAN_SLEEP);
3414         }
3415
3416         while (1) {
3417                 stm_target_mode_abort_all(priv);
3418
3419                 n = 0;
3420                 for (i = 0; i< priv->num_cmd_buffers; i++) {
3421                         if (priv->io_state[i] & IO_STATE_POSTED) {
3422                                 n++;
3423                         }
3424                 }
3425
3426                 if (n == priv->num_cmd_buffers)
3427                         break;
3428
3429                 TRACE_DBG("%s: %d out of %d commands still active, waiting...",
3430                                 ioc->name, n, priv->num_cmd_buffers);
3431                 stm_wait(priv, 10, CAN_SLEEP);
3432         }
3433
3434         TRACE_EXIT();
3435     return (0);
3436 }
3437
3438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3439 static int
3440 stm_link_serv_abort(MPT_STM_PRIV *priv)
3441 {
3442     MPT_ADAPTER         *ioc = priv->ioc;
3443     FcAbortRequest_t    *req;
3444         int ret;
3445
3446         TRACE_ENTRY();
3447
3448     req = (FcAbortRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3449     memset(req, 0, sizeof(*req));
3450
3451     req->AbortType = FC_ABORT_TYPE_ALL_FC_BUFFERS;
3452     req->Function = MPI_FUNCTION_FC_ABORT;
3453
3454     priv->link_serv_abort_pending = 1;
3455
3456     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3457
3458     ret = stm_wait_for(priv, &priv->link_serv_abort_pending, 60, NO_SLEEP);
3459
3460         TRACE_EXIT_RES(ret);
3461
3462         return ret;
3463 }
3464
3465 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3466 static int
3467 stm_reset_link(MPT_STM_PRIV *priv)
3468 {
3469     MPT_ADAPTER                 *ioc = priv->ioc;
3470     FcPrimitiveSendRequest_t    *req;
3471         int ret;
3472
3473         TRACE_ENTRY();
3474     req = (FcPrimitiveSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3475     memset(req, 0, sizeof(*req));
3476
3477     req->SendFlags = MPI_FC_PRIM_SEND_FLAGS_RESET_LINK;
3478     req->Function = MPI_FUNCTION_FC_PRIMITIVE_SEND;
3479
3480     priv->fc_primitive_send_pending = 1;
3481
3482     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3483
3484     ret = stm_wait_for(priv, &priv->fc_primitive_send_pending, 60, NO_SLEEP);
3485         TRACE_EXIT_RES(ret);
3486
3487         return ret;
3488 }
3489 #if 0
3490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3491 static int
3492 stm_login_port(MPT_STM_PRIV *priv, int port_id, int sleep)
3493 {
3494     MPT_ADAPTER                 *ioc = priv->ioc;
3495     ExLinkServiceSendRequest_t  *req;
3496     MPT_STM_SIMPLE              *sge_simple;
3497     u32                         *buf;
3498     int                         len, ret;
3499     dma_addr_t                  dma_addr;
3500
3501         TRACE_ENTRY();
3502     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3503     memset(req, 0, sizeof(*req));
3504
3505     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3506     req->MsgFlags_Did = cpu_to_le32(port_id);
3507     req->ElsCommandCode = cpu_to_le32(PLOGI);
3508
3509     len = 29 * 4;
3510     buf = priv->hw->exlink_buf;
3511     memset(buf, 0, len);
3512
3513     buf[0] = cpu_to_be32(PLOGI << 24);
3514     /*
3515      *  the firmware builds the rest of the PLOGI payload
3516      */
3517
3518     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3519     sge_simple->FlagsLength = cpu_to_le32(len |
3520         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3521                           MPI_SGE_FLAGS_END_OF_BUFFER |
3522                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3523                           MPI_SGE_FLAGS_HOST_TO_IOC));
3524     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3525     stm_set_dma_addr(sge_simple->Address, dma_addr);
3526     sge_simple++;
3527     sge_simple->FlagsLength = cpu_to_le32(len |
3528         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3529                           MPI_SGE_FLAGS_LAST_ELEMENT |
3530                           MPI_SGE_FLAGS_END_OF_BUFFER |
3531                           MPI_SGE_FLAGS_END_OF_LIST |
3532                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3533                           MPI_SGE_FLAGS_IOC_TO_HOST));
3534     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3535     stm_set_dma_addr(sge_simple->Address, dma_addr);
3536
3537     priv->ex_link_service_send_pending = 1;
3538
3539     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3540
3541     if (stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep) < 0)
3542         return (-1);
3543
3544     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3545     memset(req, 0, sizeof(*req));
3546
3547     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3548     req->MsgFlags_Did = cpu_to_le32(port_id);
3549     req->ElsCommandCode = cpu_to_le32(PRLI);
3550
3551     len = 5 * 4;
3552     buf = priv->hw->exlink_buf;
3553     memset(buf, 0, len);
3554
3555     buf[0] = cpu_to_be32(0x00100014 | (PRLI << 24));
3556     buf[1] = cpu_to_be32(0x08002000);
3557     buf[2] = cpu_to_be32(0x00000000);
3558     buf[3] = cpu_to_be32(0x00000000);
3559     buf[4] = cpu_to_be32(0x000000b2);
3560
3561     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3562     sge_simple->FlagsLength = cpu_to_le32(len |
3563         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3564                           MPI_SGE_FLAGS_END_OF_BUFFER |
3565                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3566                           MPI_SGE_FLAGS_HOST_TO_IOC));
3567     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3568     stm_set_dma_addr(sge_simple->Address, dma_addr);
3569     sge_simple++;
3570     sge_simple->FlagsLength = cpu_to_le32(len |
3571         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3572                           MPI_SGE_FLAGS_LAST_ELEMENT |
3573                           MPI_SGE_FLAGS_END_OF_BUFFER |
3574                           MPI_SGE_FLAGS_END_OF_LIST |
3575                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3576                           MPI_SGE_FLAGS_IOC_TO_HOST));
3577     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3578     stm_set_dma_addr(sge_simple->Address, dma_addr);
3579
3580     priv->ex_link_service_send_pending = 1;
3581
3582     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3583
3584     ret = stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep);
3585
3586         TRACE_EXIT_RES(ret);
3587
3588         return ret;
3589 }
3590
3591 static int
3592 stm_logout_port(MPT_STM_PRIV *priv,
3593                 int port_id, int sleep)
3594 {
3595     MPT_ADAPTER                 *ioc = priv->ioc;
3596     ExLinkServiceSendRequest_t  *req;
3597     MPT_STM_SIMPLE              *sge_simple;
3598     u32                         *buf;
3599     int                         len, ret;
3600     dma_addr_t                  dma_addr;
3601
3602         TRACE_ENTRY();
3603     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3604     memset(req, 0, sizeof(*req));
3605
3606     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3607     req->MsgFlags_Did = cpu_to_le32(port_id);
3608     req->ElsCommandCode = cpu_to_le32(LOGO);
3609
3610     len = 4 * 4;
3611     buf = priv->hw->exlink_buf;
3612     memset(buf, 0, len);
3613
3614     buf[0] = cpu_to_be32(LOGO << 24);
3615     /*
3616      *  the firmware builds the rest of the LOGO payload
3617      */
3618
3619     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3620     sge_simple->FlagsLength = cpu_to_le32(len |
3621         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3622                           MPI_SGE_FLAGS_END_OF_BUFFER |
3623                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3624                           MPI_SGE_FLAGS_HOST_TO_IOC));
3625     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3626     stm_set_dma_addr(sge_simple->Address, dma_addr);
3627     sge_simple++;
3628     sge_simple->FlagsLength = cpu_to_le32(len |
3629         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3630                           MPI_SGE_FLAGS_LAST_ELEMENT |
3631                           MPI_SGE_FLAGS_END_OF_BUFFER |
3632                           MPI_SGE_FLAGS_END_OF_LIST |
3633                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3634                           MPI_SGE_FLAGS_IOC_TO_HOST));
3635     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3636     stm_set_dma_addr(sge_simple->Address, dma_addr);
3637
3638     priv->ex_link_service_send_pending = 1;
3639
3640     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3641
3642     ret = stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep);
3643
3644         TRACE_EXIT_RES(ret);
3645
3646         return ret;
3647 }
3648
3649 static int
3650 stm_process_logout_port(MPT_STM_PRIV *priv,
3651                         int port_id, int sleep)
3652 {
3653     MPT_ADAPTER                 *ioc = priv->ioc;
3654     ExLinkServiceSendRequest_t  *req;
3655     MPT_STM_SIMPLE              *sge_simple;
3656     u32                         *buf;
3657     int                         len, ret;
3658     dma_addr_t                  dma_addr;
3659
3660         TRACE_ENTRY();
3661     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3662     memset(req, 0, sizeof(*req));
3663
3664     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3665     req->MsgFlags_Did = cpu_to_le32(port_id);
3666     req->ElsCommandCode = cpu_to_le32(PRLO);
3667
3668     len = 5 * 4;
3669     buf = priv->hw->exlink_buf;
3670     memset(buf, 0, len);
3671
3672     buf[0] = cpu_to_be32(0x00100014 | (PRLO << 24));
3673     buf[1] = cpu_to_be32(0x08002000);
3674     buf[2] = cpu_to_be32(0x00000000);
3675     buf[3] = cpu_to_be32(0x00000000);
3676     buf[4] = cpu_to_be32(0x00000000);
3677
3678     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3679     sge_simple->FlagsLength = cpu_