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