1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/* fcp_impl.h: Generic SCSI on top of FC4 - our interface defines.
*
* Copyright (C) 1997-1999 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1998 Jirka Hanika (geo@ff.cuni.cz)
*/
#ifndef _FCP_SCSI_H
#define _FCP_SCSI_H
#include <linux/types.h>
#include <linux/blk.h>
#include "../scsi/scsi.h"
#include "fc.h"
#include "fcp.h"
#include "fc-al.h"
#include <asm/io.h>
#ifdef __sparc__
#include <asm/sbus.h>
#endif
/* 0 or 1 */
#define FCP_SCSI_USE_NEW_EH_CODE 0
#define FC_CLASS_OUTBOUND 0x01
#define FC_CLASS_INBOUND 0x02
#define FC_CLASS_SIMPLE 0x03
#define FC_CLASS_IO_WRITE 0x04
#define FC_CLASS_IO_READ 0x05
#define FC_CLASS_UNSOLICITED 0x06
#define FC_CLASS_OFFLINE 0x08
#define PROTO_OFFLINE 0x02
#define PROTO_REPORT_AL_MAP 0x03
#define PROTO_FORCE_LIP 0x06
struct _fc_channel;
typedef struct fcp_cmnd {
struct fcp_cmnd *next;
struct fcp_cmnd *prev;
void (*done)(Scsi_Cmnd *);
unsigned short proto;
unsigned short token;
unsigned int did;
/* FCP SCSI stuff */
dma_addr_t data;
/* From now on this cannot be touched for proto == TYPE_SCSI_FCP */
fc_hdr fch;
dma_addr_t cmd;
dma_addr_t rsp;
int cmdlen;
int rsplen;
int class;
int datalen;
/* This is just used as a verification during login */
struct _fc_channel *fc;
void *ls;
} fcp_cmnd;
typedef struct {
unsigned int len;
unsigned char list[0];
} fcp_posmap;
typedef struct _fc_channel {
struct _fc_channel *next;
int irq;
int state;
int sid;
int did;
char name[16];
void (*fcp_register)(struct _fc_channel *, u8, int);
void (*reset)(struct _fc_channel *);
int (*hw_enque)(struct _fc_channel *, fcp_cmnd *);
fc_wwn wwn_node;
fc_wwn wwn_nport;
fc_wwn wwn_dest;
common_svc_parm *common_svc;
svc_parm *class_svcs;
#ifdef __sparc__
struct sbus_dev *dev;
#else
struct pci_dev *dev;
#endif
struct module *module;
/* FCP SCSI stuff */
short can_queue;
short abort_count;
int rsp_size;
fcp_cmd *scsi_cmd_pool;
char *scsi_rsp_pool;
dma_addr_t dma_scsi_cmd, dma_scsi_rsp;
long *scsi_bitmap;
long scsi_bitmap_end;
int scsi_free;
int (*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
fcp_cmnd *scsi_que;
char scsi_name[4];
fcp_cmnd **cmd_slots;
int channels;
int targets;
long *ages;
Scsi_Cmnd *rst_pkt;
fcp_posmap *posmap;
/* LOGIN stuff */
fcp_cmnd *login;
void *ls;
} fc_channel;
extern fc_channel *fc_channels;
#define FC_STATE_UNINITED 0
#define FC_STATE_ONLINE 1
#define FC_STATE_OFFLINE 2
#define FC_STATE_RESETING 3
#define FC_STATE_FPORT_OK 4
#define FC_STATE_MAYBEOFFLINE 5
#define FC_STATUS_OK 0
#define FC_STATUS_P_RJT 2
#define FC_STATUS_F_RJT 3
#define FC_STATUS_P_BSY 4
#define FC_STATUS_F_BSY 5
#define FC_STATUS_ERR_OFFLINE 0x11
#define FC_STATUS_TIMEOUT 0x12
#define FC_STATUS_ERR_OVERRUN 0x13
#define FC_STATUS_POINTTOPOINT 0x15
#define FC_STATUS_AL 0x16
#define FC_STATUS_UNKNOWN_CQ_TYPE 0x20
#define FC_STATUS_BAD_SEG_CNT 0x21
#define FC_STATUS_MAX_XCHG_EXCEEDED 0x22
#define FC_STATUS_BAD_XID 0x23
#define FC_STATUS_XCHG_BUSY 0x24
#define FC_STATUS_BAD_POOL_ID 0x25
#define FC_STATUS_INSUFFICIENT_CQES 0x26
#define FC_STATUS_ALLOC_FAIL 0x27
#define FC_STATUS_BAD_SID 0x28
#define FC_STATUS_NO_SEQ_INIT 0x29
#define FC_STATUS_TIMED_OUT -1
#define FC_STATUS_BAD_RSP -2
void fcp_queue_empty(fc_channel *);
int fcp_init(fc_channel *);
void fcp_release(fc_channel *fc_chain, int count);
void fcp_receive_solicited(fc_channel *, int, int, int, fc_hdr *);
void fcp_state_change(fc_channel *, int);
int fc_do_plogi(fc_channel *, unsigned char, fc_wwn *, fc_wwn *);
int fc_do_prli(fc_channel *, unsigned char);
#define for_each_fc_channel(fc) \
for (fc = fc_channels; fc; fc = fc->next)
#define for_each_online_fc_channel(fc) \
for_each_fc_channel(fc) \
if (fc->state == FC_STATE_ONLINE)
int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int fcp_old_abort(Scsi_Cmnd *);
int fcp_scsi_abort(Scsi_Cmnd *);
int fcp_scsi_dev_reset(Scsi_Cmnd *);
int fcp_scsi_bus_reset(Scsi_Cmnd *);
int fcp_scsi_host_reset(Scsi_Cmnd *);
#endif /* !(_FCP_SCSI_H) */
|