diff options
Diffstat (limited to 'libdde_linux26/contrib/include/scsi')
77 files changed, 21260 insertions, 0 deletions
diff --git a/libdde_linux26/contrib/include/scsi/.svn/all-wcprops b/libdde_linux26/contrib/include/scsi/.svn/all-wcprops new file mode 100644 index 00000000..25199751 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/all-wcprops @@ -0,0 +1,227 @@ +K 25 +svn:wc:ra_dav:version-url +V 71 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi +END +scsi_ioctl.h +K 25 +svn:wc:ra_dav:version-url +V 84 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_ioctl.h +END +scsi_tgt_if.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_tgt_if.h +END +scsi_netlink_fc.h +K 25 +svn:wc:ra_dav:version-url +V 89 +/repos/tudos/!svn/ver/174/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_netlink_fc.h +END +scsi_host.h +K 25 +svn:wc:ra_dav:version-url +V 83 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_host.h +END +fc_transport_fcoe.h +K 25 +svn:wc:ra_dav:version-url +V 91 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/fc_transport_fcoe.h +END +scsi.h +K 25 +svn:wc:ra_dav:version-url +V 78 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi.h +END +scsi_transport_srp.h +K 25 +svn:wc:ra_dav:version-url +V 92 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport_srp.h +END +fc_frame.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/fc_frame.h +END +fc_encode.h +K 25 +svn:wc:ra_dav:version-url +V 83 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/fc_encode.h +END +scsi_transport_iscsi.h +K 25 +svn:wc:ra_dav:version-url +V 94 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport_iscsi.h +END +libiscsi_tcp.h +K 25 +svn:wc:ra_dav:version-url +V 86 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libiscsi_tcp.h +END +sg.h +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/sg.h +END +scsi_eh.h +K 25 +svn:wc:ra_dav:version-url +V 81 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_eh.h +END +scsicam.h +K 25 +svn:wc:ra_dav:version-url +V 81 +/repos/tudos/!svn/ver/174/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsicam.h +END +scsi_transport_sas.h +K 25 +svn:wc:ra_dav:version-url +V 92 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport_sas.h +END +scsi_transport_fc.h +K 25 +svn:wc:ra_dav:version-url +V 91 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport_fc.h +END +scsi_netlink.h +K 25 +svn:wc:ra_dav:version-url +V 86 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_netlink.h +END +iscsi_if.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/iscsi_if.h +END +libsrp.h +K 25 +svn:wc:ra_dav:version-url +V 80 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libsrp.h +END +iscsi_proto.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/iscsi_proto.h +END +libiscsi.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libiscsi.h +END +scsi_cmnd.h +K 25 +svn:wc:ra_dav:version-url +V 83 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_cmnd.h +END +libfcoe.h +K 25 +svn:wc:ra_dav:version-url +V 81 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libfcoe.h +END +srp.h +K 25 +svn:wc:ra_dav:version-url +V 77 +/repos/tudos/!svn/ver/174/trunk/l4/pkg/dde/linux26/contrib/include/scsi/srp.h +END +scsi_tcq.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_tcq.h +END +scsi_devinfo.h +K 25 +svn:wc:ra_dav:version-url +V 86 +/repos/tudos/!svn/ver/174/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_devinfo.h +END +sas_ata.h +K 25 +svn:wc:ra_dav:version-url +V 81 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/sas_ata.h +END +scsi_driver.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_driver.h +END +scsi_dh.h +K 25 +svn:wc:ra_dav:version-url +V 81 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_dh.h +END +scsi_transport.h +K 25 +svn:wc:ra_dav:version-url +V 88 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport.h +END +libsas.h +K 25 +svn:wc:ra_dav:version-url +V 80 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libsas.h +END +scsi_dbg.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_dbg.h +END +scsi_tgt.h +K 25 +svn:wc:ra_dav:version-url +V 82 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_tgt.h +END +libfc.h +K 25 +svn:wc:ra_dav:version-url +V 79 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/libfc.h +END +scsi_device.h +K 25 +svn:wc:ra_dav:version-url +V 85 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_device.h +END +sas.h +K 25 +svn:wc:ra_dav:version-url +V 77 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/sas.h +END +scsi_transport_spi.h +K 25 +svn:wc:ra_dav:version-url +V 92 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/contrib/include/scsi/scsi_transport_spi.h +END diff --git a/libdde_linux26/contrib/include/scsi/.svn/entries b/libdde_linux26/contrib/include/scsi/.svn/entries new file mode 100644 index 00000000..f4a6b5f2 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/entries @@ -0,0 +1,1286 @@ +9 + +dir +465 +http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/contrib/include/scsi +http://svn.tudos.org/repos/tudos + + + +2009-05-20T14:32:55.606606Z +455 +l4check + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +a704ac0b-3a55-4d43-a2a9-7be6f07c34fb + +scsi_ioctl.h +file + + + + +2009-11-15T17:16:21.000000Z +25c7e4989d8a4b4ce378b57c6f508d26 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1259 + +scsi_tgt_if.h +file + + + + +2009-11-15T17:16:21.000000Z +2b885494711c83d0d7f9ffd41ff9f705 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +2533 + +scsi_netlink_fc.h +file + + + + +2009-11-15T17:16:21.000000Z +60a827a5babf64d5560c01c8a3d9489c +2007-09-08T19:44:13.897747Z +174 +l4check + + + + + + + + + + + + + + + + + + + + + +1929 + +scsi_host.h +file + + + + +2009-11-15T17:16:21.000000Z +9fdf9ac1d477c4bafa991626a8fc9a18 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +26620 + +fc_transport_fcoe.h +file + + + + +2009-11-15T17:16:21.000000Z +39928246068e1425ebb3677098548613 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1674 + +scsi.h +file + + + + +2009-11-15T17:16:21.000000Z +3f72fea39fb5a814d7b1aa48fc048033 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +16690 + +scsi_transport_srp.h +file + + + + +2009-11-15T17:16:21.000000Z +21ede6beb25fa84d11a87b339ee0de8c +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +902 + +fc_frame.h +file + + + + +2009-11-15T17:16:21.000000Z +0811410e0dd1eef1f0e7f47c93d92c07 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +6737 + +fc_encode.h +file + + + + +2009-11-15T17:16:21.000000Z +72da6026bd0329c3f799ffe743564959 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +7916 + +scsi_transport_iscsi.h +file + + + + +2009-11-15T17:16:21.000000Z +8d7a5364e4c1de9ea8aaf57f84deffe4 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +9551 + +libiscsi_tcp.h +file + + + + +2009-11-15T17:16:21.000000Z +d5d552f3aa0d828d3e9a827e2434bac2 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4253 + +sg.h +file + + + + +2009-11-15T17:16:21.000000Z +52f0a5ec48f574780361ceea18ccbcbc +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +14354 + +scsi_eh.h +file + + + + +2009-11-15T17:16:21.000000Z +fad567da7a5aa983a8be3391fa290ce0 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +2773 + +scsicam.h +file + + + + +2009-11-15T17:16:21.000000Z +1aef6f1ddc8772dbdc4b7ab1917fe3e1 +2007-09-08T19:44:13.897747Z +174 +l4check + + + + + + + + + + + + + + + + + + + + + +674 + +scsi_transport_sas.h +file + + + + +2009-11-15T17:16:21.000000Z +8ceda6967a06c96ee488dc8e1d5a65cd +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +6223 + +scsi_transport_fc.h +file + + + + +2009-11-15T17:16:21.000000Z +c058027f72dd6bfb92117a42f2e9e8f4 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +24516 + +scsi_netlink.h +file + + + + +2009-11-15T17:16:21.000000Z +aa870516f7ee63267ffdd58dbe18cb3c +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4349 + +iscsi_if.h +file + + + + +2009-11-15T17:16:21.000000Z +55b47d5617e4952f8fd0885a02b47146 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +11741 + +libsrp.h +file + + + + +2009-11-15T17:16:21.000000Z +c7afb49d1d83aa3157f6c073ed90c9a6 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1557 + +iscsi_proto.h +file + + + + +2009-11-15T17:16:21.000000Z +717fc6b96c4d688803ddf7f757a9e466 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +15290 + +libiscsi.h +file + + + + +2009-11-15T17:16:21.000000Z +6e32ad7ae34844e4c1e1373749d5b093 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +12588 + +scsi_cmnd.h +file + + + + +2009-11-15T17:16:21.000000Z +522f212a80ff88fddfb2f739feb74fee +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +8223 + +libfcoe.h +file + + + + +2009-11-15T17:16:21.000000Z +e59559edc44016b02931b6d355cd5826 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4768 + +srp.h +file + + + + +2009-11-15T17:16:21.000000Z +b31a2a6a83a558af67402e54972d1f85 +2007-09-08T19:44:13.897747Z +174 +l4check + + + + + + + + + + + + + + + + + + + + + +5621 + +scsi_tcq.h +file + + + + +2009-11-15T17:16:21.000000Z +6ae7d73f63683d271f6795b3b4749797 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4378 + +scsi_devinfo.h +file + + + + +2009-11-15T17:16:21.000000Z +1eb232ae25e25168f5384bbbb29c57e6 +2007-09-08T19:44:13.897747Z +174 +l4check + + + + + + + + + + + + + + + + + + + + + +1909 + +sas_ata.h +file + + + + +2009-11-15T17:16:21.000000Z +9951a622afb2667638053bff994dff28 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1630 + +scsi_driver.h +file + + + + +2009-11-15T17:16:21.000000Z +c63712cedf45c883103bd6522de432d4 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +995 + +scsi_dh.h +file + + + + +2009-11-15T17:16:21.000000Z +670a42e054af69b911b02476bba37a7f +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +2421 + +libsas.h +file + + + + +2009-11-15T17:16:21.000000Z +2143790f97eec2b82b64bdf0a6b1ae33 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +17866 + +scsi_dbg.h +file + + + + +2009-11-15T17:16:21.000000Z +aff3e4adb315aaa615a766037778b0f5 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +968 + +scsi_transport.h +file + + + + +2009-11-15T17:16:21.000000Z +c50daa8d211059c510eaa010106371b9 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +3980 + +scsi_tgt.h +file + + + + +2009-11-15T17:16:21.000000Z +c72f1c247a70c300fca3b18ee1509667 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +807 + +libfc.h +file + + + + +2009-11-15T17:16:21.000000Z +540378fdc2fc209d14f3c7d208ad3eda +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +24513 + +scsi_device.h +file + + + + +2009-11-15T17:16:21.000000Z +06658e3c7a79c727b0ba830608e2b8d2 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +16710 + +sas.h +file + + + + +2009-11-15T17:16:21.000000Z +1a257839d415cfe11bc91bf570de78aa +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +11943 + +scsi_transport_spi.h +file + + + + +2009-11-15T17:16:21.000000Z +86495f5432fc9aff2e94ab5dc67ccd5e +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +7083 + diff --git a/libdde_linux26/contrib/include/scsi/.svn/format b/libdde_linux26/contrib/include/scsi/.svn/format new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/format @@ -0,0 +1 @@ +9 diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_encode.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_encode.h.svn-base new file mode 100644 index 00000000..6300f556 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_encode.h.svn-base @@ -0,0 +1,309 @@ +/* + * Copyright(c) 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_ENCODE_H_ +#define _FC_ENCODE_H_ +#include <asm/unaligned.h> + +struct fc_ns_rft { + struct fc_ns_fid fid; /* port ID object */ + struct fc_ns_fts fts; /* FC4-types object */ +}; + +struct fc_ct_req { + struct fc_ct_hdr hdr; + union { + struct fc_ns_gid_ft gid; + struct fc_ns_rn_id rn; + struct fc_ns_rft rft; + } payload; +}; + +/** + * fill FC header fields in specified fc_frame + */ +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, + u32 did, u32 sid, enum fc_fh_type type, + u32 f_ctl, u32 parm_offset) +{ + struct fc_frame_header *fh; + + fh = fc_frame_header_get(fp); + WARN_ON(r_ctl == 0); + fh->fh_r_ctl = r_ctl; + hton24(fh->fh_d_id, did); + hton24(fh->fh_s_id, sid); + fh->fh_type = type; + hton24(fh->fh_f_ctl, f_ctl); + fh->fh_cs_ctl = 0; + fh->fh_df_ctl = 0; + fh->fh_parm_offset = htonl(parm_offset); +} + +/** + * fc_ct_hdr_fill- fills ct header and reset ct payload + * returns pointer to ct request. + */ +static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, + unsigned int op, size_t req_size) +{ + struct fc_ct_req *ct; + size_t ct_plen; + + ct_plen = sizeof(struct fc_ct_hdr) + req_size; + ct = fc_frame_payload_get(fp, ct_plen); + memset(ct, 0, ct_plen); + ct->hdr.ct_rev = FC_CT_REV; + ct->hdr.ct_fs_type = FC_FST_DIR; + ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; + ct->hdr.ct_cmd = htons((u16) op); + return ct; +} + +/** + * fc_ct_fill - Fill in a name service request frame + */ +static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op, enum fc_rctl *r_ctl, u32 *did, + enum fc_fh_type *fh_type) +{ + struct fc_ct_req *ct; + + switch (op) { + case FC_NS_GPN_FT: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; + break; + + case FC_NS_RFT_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); + hton24(ct->payload.rft.fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + break; + + case FC_NS_RPN_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); + hton24(ct->payload.rn.fr_fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + *r_ctl = FC_RCTL_DD_UNSOL_CTL; + *did = FC_FID_DIR_SERV; + *fh_type = FC_TYPE_CT; + return 0; +} + +/** + * fc_plogi_fill - Fill in plogi request frame + */ +static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op) +{ + struct fc_els_flogi *plogi; + struct fc_els_csp *csp; + struct fc_els_cssp *cp; + + plogi = fc_frame_payload_get(fp, sizeof(*plogi)); + memset(plogi, 0, sizeof(*plogi)); + plogi->fl_cmd = (u8) op; + put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); + + csp = &plogi->fl_csp; + csp->sp_hi_ver = 0x20; + csp->sp_lo_ver = 0x20; + csp->sp_bb_cred = htons(10); /* this gets set by gateway */ + csp->sp_bb_data = htons((u16) lport->mfs); + cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); + csp->sp_features = htons(FC_SP_FT_CIRO); + csp->sp_tot_seq = htons(255); /* seq. we accept */ + csp->sp_rel_off = htons(0x1f); + csp->sp_e_d_tov = htonl(lport->e_d_tov); + + cp->cp_rdfs = htons((u16) lport->mfs); + cp->cp_con_seq = htons(255); + cp->cp_open_seq = 1; +} + +/** + * fc_flogi_fill - Fill in a flogi request frame. + */ +static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_csp *sp; + struct fc_els_cssp *cp; + struct fc_els_flogi *flogi; + + flogi = fc_frame_payload_get(fp, sizeof(*flogi)); + memset(flogi, 0, sizeof(*flogi)); + flogi->fl_cmd = (u8) ELS_FLOGI; + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); + sp = &flogi->fl_csp; + sp->sp_hi_ver = 0x20; + sp->sp_lo_ver = 0x20; + sp->sp_bb_cred = htons(10); /* this gets set by gateway */ + sp->sp_bb_data = htons((u16) lport->mfs); + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); +} + +/** + * fc_logo_fill - Fill in a logo request frame. + */ +static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_logo *logo; + + logo = fc_frame_payload_get(fp, sizeof(*logo)); + memset(logo, 0, sizeof(*logo)); + logo->fl_cmd = ELS_LOGO; + hton24(logo->fl_n_port_id, fc_host_port_id(lport->host)); + logo->fl_n_port_wwn = htonll(lport->wwpn); +} + +/** + * fc_rtv_fill - Fill in RTV (read timeout value) request frame. + */ +static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rtv *rtv; + + rtv = fc_frame_payload_get(fp, sizeof(*rtv)); + memset(rtv, 0, sizeof(*rtv)); + rtv->rtv_cmd = ELS_RTV; +} + +/** + * fc_rec_fill - Fill in rec request frame + */ +static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rec *rec; + struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); + + rec = fc_frame_payload_get(fp, sizeof(*rec)); + memset(rec, 0, sizeof(*rec)); + rec->rec_cmd = ELS_REC; + hton24(rec->rec_s_id, fc_host_port_id(lport->host)); + rec->rec_ox_id = htons(ep->oxid); + rec->rec_rx_id = htons(ep->rxid); +} + +/** + * fc_prli_fill - Fill in prli request frame + */ +static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct { + struct fc_els_prli prli; + struct fc_els_spp spp; + } *pp; + + pp = fc_frame_payload_get(fp, sizeof(*pp)); + memset(pp, 0, sizeof(*pp)); + pp->prli.prli_cmd = ELS_PRLI; + pp->prli.prli_spp_len = sizeof(struct fc_els_spp); + pp->prli.prli_len = htons(sizeof(*pp)); + pp->spp.spp_type = FC_TYPE_FCP; + pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; + pp->spp.spp_params = htonl(lport->service_params); +} + +/** + * fc_scr_fill - Fill in a scr request frame. + */ +static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_scr *scr; + + scr = fc_frame_payload_get(fp, sizeof(*scr)); + memset(scr, 0, sizeof(*scr)); + scr->scr_cmd = ELS_SCR; + scr->scr_reg_func = ELS_SCRF_FULL; +} + +/** + * fc_els_fill - Fill in an ELS request frame + */ +static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport, + struct fc_frame *fp, unsigned int op, + enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type) +{ + switch (op) { + case ELS_PLOGI: + fc_plogi_fill(lport, fp, ELS_PLOGI); + *did = rport->port_id; + break; + + case ELS_FLOGI: + fc_flogi_fill(lport, fp); + *did = FC_FID_FLOGI; + break; + + case ELS_LOGO: + fc_logo_fill(lport, fp); + *did = FC_FID_FLOGI; + /* + * if rport is valid then it + * is port logo, therefore + * set did to rport id. + */ + if (rport) + *did = rport->port_id; + break; + + case ELS_RTV: + fc_rtv_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_REC: + fc_rec_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_PRLI: + fc_prli_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_SCR: + fc_scr_fill(lport, fp); + *did = FC_FID_FCTRL; + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + + *r_ctl = FC_RCTL_ELS_REQ; + *fh_type = FC_TYPE_ELS; + return 0; +} +#endif /* _FC_ENCODE_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_frame.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_frame.h.svn-base new file mode 100644 index 00000000..04d34a71 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_frame.h.svn-base @@ -0,0 +1,242 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FRAME_H_ +#define _FC_FRAME_H_ + +#include <linux/scatterlist.h> +#include <linux/skbuff.h> +#include <scsi/scsi_cmnd.h> + +#include <scsi/fc/fc_fs.h> +#include <scsi/fc/fc_fcp.h> +#include <scsi/fc/fc_encaps.h> + +/* + * The fc_frame interface is used to pass frame data between functions. + * The frame includes the data buffer, length, and SOF / EOF delimiter types. + * A pointer to the port structure of the receiving port is also includeded. + */ + +#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */ +#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */ + +/* + * Information about an individual fibre channel frame received or to be sent. + * The buffer may be in up to 4 additional non-contiguous sections, + * but the linear section must hold the frame header. + */ +#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */ + +#define fp_skb(fp) (&((fp)->skb)) +#define fr_hdr(fp) ((fp)->skb.data) +#define fr_len(fp) ((fp)->skb.len) +#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0])) +#define fr_dev(fp) (fr_cb(fp)->fr_dev) +#define fr_seq(fp) (fr_cb(fp)->fr_seq) +#define fr_sof(fp) (fr_cb(fp)->fr_sof) +#define fr_eof(fp) (fr_cb(fp)->fr_eof) +#define fr_flags(fp) (fr_cb(fp)->fr_flags) +#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) +#define fr_cmd(fp) (fr_cb(fp)->fr_cmd) +#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction) +#define fr_crc(fp) (fr_cb(fp)->fr_crc) + +struct fc_frame { + struct sk_buff skb; +}; + +struct fcoe_rcv_info { + struct packet_type *ptype; + struct fc_lport *fr_dev; /* transport layer private pointer */ + struct fc_seq *fr_seq; /* for use with exchange manager */ + struct scsi_cmnd *fr_cmd; /* for use of scsi command */ + u32 fr_crc; + u16 fr_max_payload; /* max FC payload */ + enum fc_sof fr_sof; /* start of frame delimiter */ + enum fc_eof fr_eof; /* end of frame delimiter */ + u8 fr_flags; /* flags - see below */ +}; + + +/* + * Get fc_frame pointer for an skb that's already been imported. + */ +static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb)); + return (struct fcoe_rcv_info *) skb->cb; +} + +/* + * fr_flags. + */ +#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */ + +/* + * Initialize a frame. + * We don't do a complete memset here for performance reasons. + * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually. + */ +static inline void fc_frame_init(struct fc_frame *fp) +{ + fr_dev(fp) = NULL; + fr_seq(fp) = NULL; + fr_flags(fp) = 0; +} + +struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len); + +struct fc_frame *__fc_frame_alloc(size_t payload_len); + +/* + * Get frame for sending via port. + */ +static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev, + size_t payload_len) +{ + return __fc_frame_alloc(payload_len); +} + +/* + * Allocate fc_frame structure and buffer. Set the initial length to + * payload_size + sizeof (struct fc_frame_header). + */ +static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len) +{ + struct fc_frame *fp; + + /* + * Note: Since len will often be a constant multiple of 4, + * this check will usually be evaluated and eliminated at compile time. + */ + if ((len % 4) != 0) + fp = fc_frame_alloc_fill(dev, len); + else + fp = _fc_frame_alloc(dev, len); + return fp; +} + +/* + * Free the fc_frame structure and buffer. + */ +static inline void fc_frame_free(struct fc_frame *fp) +{ + kfree_skb(fp_skb(fp)); +} + +static inline int fc_frame_is_linear(struct fc_frame *fp) +{ + return !skb_is_nonlinear(fp_skb(fp)); +} + +/* + * Get frame header from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + */ +static inline +struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp) +{ + WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header)); + return (struct fc_frame_header *) fr_hdr(fp); +} + +/* + * Get frame payload from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + * The len parameter is the minimum length for the payload portion. + * Returns NULL if the frame is too short. + * + * This assumes the interesting part of the payload is in the first part + * of the buffer for received data. This may not be appropriate to use for + * buffers being transmitted. + */ +static inline void *fc_frame_payload_get(const struct fc_frame *fp, + size_t len) +{ + void *pp = NULL; + + if (fr_len(fp) >= sizeof(struct fc_frame_header) + len) + pp = fc_frame_header_get(fp) + 1; + return pp; +} + +/* + * Get frame payload opcode (first byte) from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. Return 0 + * if the frame has no payload. + */ +static inline u8 fc_frame_payload_op(const struct fc_frame *fp) +{ + u8 *cp; + + cp = fc_frame_payload_get(fp, sizeof(u8)); + if (!cp) + return 0; + return *cp; + +} + +/* + * Get FC class from frame. + */ +static inline enum fc_class fc_frame_class(const struct fc_frame *fp) +{ + return fc_sof_class(fr_sof(fp)); +} + +/* + * Check the CRC in a frame. + * The CRC immediately follows the last data item *AFTER* the length. + * The return value is zero if the CRC matches. + */ +u32 fc_frame_crc_check(struct fc_frame *); + +static inline u8 fc_frame_rctl(const struct fc_frame *fp) +{ + return fc_frame_header_get(fp)->fh_r_ctl; +} + +static inline bool fc_frame_is_cmd(const struct fc_frame *fp) +{ + return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool fc_frame_is_read(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_FROM_DEVICE; + return false; +} + +static inline bool fc_frame_is_write(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_TO_DEVICE; + return false; +} + +/* + * Check for leaks. + * Print the frame header of any currently allocated frame, assuming there + * should be none at this point. + */ +void fc_frame_leak_check(void); + +#endif /* _FC_FRAME_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_transport_fcoe.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_transport_fcoe.h.svn-base new file mode 100644 index 00000000..8dca2af1 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/fc_transport_fcoe.h.svn-base @@ -0,0 +1,54 @@ +#ifndef FC_TRANSPORT_FCOE_H +#define FC_TRANSPORT_FCOE_H + +#include <linux/device.h> +#include <linux/netdevice.h> +#include <scsi/scsi_host.h> +#include <scsi/libfc.h> + +/** + * struct fcoe_transport - FCoE transport struct for generic transport + * for Ethernet devices as well as pure HBAs + * + * @name: name for thsi transport + * @bus: physical bus type (pci_bus_type) + * @driver: physical bus driver for network device + * @create: entry create function + * @destroy: exit destroy function + * @list: list of transports + */ +struct fcoe_transport { + char *name; + unsigned short vendor; + unsigned short device; + struct bus_type *bus; + struct device_driver *driver; + int (*create)(struct net_device *device); + int (*destroy)(struct net_device *device); + bool (*match)(struct net_device *device); + struct list_head list; + struct list_head devlist; + struct mutex devlock; +}; + +/** + * MODULE_ALIAS_FCOE_PCI + * + * some care must be taken with this, vendor and device MUST be a hex value + * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB) + */ +#define MODULE_ALIAS_FCOE_PCI(vendor, device) \ + MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device)) + +/* exported funcs */ +int fcoe_transport_attach(struct net_device *netdev); +int fcoe_transport_release(struct net_device *netdev); +int fcoe_transport_register(struct fcoe_transport *t); +int fcoe_transport_unregister(struct fcoe_transport *t); +int fcoe_load_transport_driver(struct net_device *netdev); +int __init fcoe_transport_init(void); +int __exit fcoe_transport_exit(void); + +/* fcow_sw is the default transport */ +extern struct fcoe_transport fcoe_sw_transport; +#endif /* FC_TRANSPORT_FCOE_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_if.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_if.h.svn-base new file mode 100644 index 00000000..d0ed5226 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_if.h.svn-base @@ -0,0 +1,401 @@ +/* + * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc) + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_IF_H +#define ISCSI_IF_H + +#include <scsi/iscsi_proto.h> + +#define UEVENT_BASE 10 +#define KEVENT_BASE 100 +#define ISCSI_ERR_BASE 1000 + +enum iscsi_uevent_e { + ISCSI_UEVENT_UNKNOWN = 0, + + /* down events */ + ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1, + ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2, + ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3, + ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4, + ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5, + ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6, + ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7, + ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8, + ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9, + ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10, + ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11, + + ISCSI_UEVENT_TRANSPORT_EP_CONNECT = UEVENT_BASE + 12, + ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, + ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, + + ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, + ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16, + ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17, + ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, + + /* up events */ + ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, + ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, + ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, + ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, + ISCSI_KEVENT_UNBIND_SESSION = KEVENT_BASE + 5, + ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6, +}; + +enum iscsi_tgt_dscvr { + ISCSI_TGT_DSCVR_SEND_TARGETS = 1, + ISCSI_TGT_DSCVR_ISNS = 2, + ISCSI_TGT_DSCVR_SLP = 3, +}; + +struct iscsi_uevent { + uint32_t type; /* k/u events type */ + uint32_t iferror; /* carries interface or resource errors */ + uint64_t transport_handle; + + union { + /* messages u -> k */ + struct msg_create_session { + uint32_t initial_cmdsn; + uint16_t cmds_max; + uint16_t queue_depth; + } c_session; + struct msg_create_bound_session { + uint64_t ep_handle; + uint32_t initial_cmdsn; + uint16_t cmds_max; + uint16_t queue_depth; + } c_bound_session; + struct msg_destroy_session { + uint32_t sid; + } d_session; + struct msg_create_conn { + uint32_t sid; + uint32_t cid; + } c_conn; + struct msg_bind_conn { + uint32_t sid; + uint32_t cid; + uint64_t transport_eph; + uint32_t is_leading; + } b_conn; + struct msg_destroy_conn { + uint32_t sid; + uint32_t cid; + } d_conn; + struct msg_send_pdu { + uint32_t sid; + uint32_t cid; + uint32_t hdr_size; + uint32_t data_size; + } send_pdu; + struct msg_set_param { + uint32_t sid; + uint32_t cid; + uint32_t param; /* enum iscsi_param */ + uint32_t len; + } set_param; + struct msg_start_conn { + uint32_t sid; + uint32_t cid; + } start_conn; + struct msg_stop_conn { + uint32_t sid; + uint32_t cid; + uint64_t conn_handle; + uint32_t flag; + } stop_conn; + struct msg_get_stats { + uint32_t sid; + uint32_t cid; + } get_stats; + struct msg_transport_connect { + uint32_t non_blocking; + } ep_connect; + struct msg_transport_poll { + uint64_t ep_handle; + uint32_t timeout_ms; + } ep_poll; + struct msg_transport_disconnect { + uint64_t ep_handle; + } ep_disconnect; + struct msg_tgt_dscvr { + enum iscsi_tgt_dscvr type; + uint32_t host_no; + /* + * enable = 1 to establish a new connection + * with the server. enable = 0 to disconnect + * from the server. Used primarily to switch + * from one iSNS server to another. + */ + uint32_t enable; + } tgt_dscvr; + struct msg_set_host_param { + uint32_t host_no; + uint32_t param; /* enum iscsi_host_param */ + uint32_t len; + } set_host_param; + } u; + union { + /* messages k -> u */ + int retcode; + struct msg_create_session_ret { + uint32_t sid; + uint32_t host_no; + } c_session_ret; + struct msg_create_conn_ret { + uint32_t sid; + uint32_t cid; + } c_conn_ret; + struct msg_unbind_session { + uint32_t sid; + uint32_t host_no; + } unbind_session; + struct msg_recv_req { + uint32_t sid; + uint32_t cid; + uint64_t recv_handle; + } recv_req; + struct msg_conn_error { + uint32_t sid; + uint32_t cid; + uint32_t error; /* enum iscsi_err */ + } connerror; + struct msg_session_destroyed { + uint32_t host_no; + uint32_t sid; + } d_session; + struct msg_transport_connect_ret { + uint64_t handle; + } ep_connect_ret; + } r; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +/* + * Common error codes + */ +enum iscsi_err { + ISCSI_OK = 0, + + ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1, + ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2, + ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3, + ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4, + ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5, + ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6, + ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7, + ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8, + ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9, + ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10, + ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11, + ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12, + ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13, + ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14, + ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, + ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16, + ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17, + ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18, + ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, +}; + +/* + * iSCSI Parameters (RFC3720) + */ +enum iscsi_param { + /* passed in using netlink set param */ + ISCSI_PARAM_MAX_RECV_DLENGTH, + ISCSI_PARAM_MAX_XMIT_DLENGTH, + ISCSI_PARAM_HDRDGST_EN, + ISCSI_PARAM_DATADGST_EN, + ISCSI_PARAM_INITIAL_R2T_EN, + ISCSI_PARAM_MAX_R2T, + ISCSI_PARAM_IMM_DATA_EN, + ISCSI_PARAM_FIRST_BURST, + ISCSI_PARAM_MAX_BURST, + ISCSI_PARAM_PDU_INORDER_EN, + ISCSI_PARAM_DATASEQ_INORDER_EN, + ISCSI_PARAM_ERL, + ISCSI_PARAM_IFMARKER_EN, + ISCSI_PARAM_OFMARKER_EN, + ISCSI_PARAM_EXP_STATSN, + ISCSI_PARAM_TARGET_NAME, + ISCSI_PARAM_TPGT, + ISCSI_PARAM_PERSISTENT_ADDRESS, + ISCSI_PARAM_PERSISTENT_PORT, + ISCSI_PARAM_SESS_RECOVERY_TMO, + + /* pased in through bind conn using transport_fd */ + ISCSI_PARAM_CONN_PORT, + ISCSI_PARAM_CONN_ADDRESS, + + ISCSI_PARAM_USERNAME, + ISCSI_PARAM_USERNAME_IN, + ISCSI_PARAM_PASSWORD, + ISCSI_PARAM_PASSWORD_IN, + + ISCSI_PARAM_FAST_ABORT, + ISCSI_PARAM_ABORT_TMO, + ISCSI_PARAM_LU_RESET_TMO, + ISCSI_PARAM_HOST_RESET_TMO, + + ISCSI_PARAM_PING_TMO, + ISCSI_PARAM_RECV_TMO, + + ISCSI_PARAM_IFACE_NAME, + ISCSI_PARAM_ISID, + ISCSI_PARAM_INITIATOR_NAME, + /* must always be last */ + ISCSI_PARAM_MAX, +}; + +#define ISCSI_MAX_RECV_DLENGTH (1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH) +#define ISCSI_MAX_XMIT_DLENGTH (1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH) +#define ISCSI_HDRDGST_EN (1ULL << ISCSI_PARAM_HDRDGST_EN) +#define ISCSI_DATADGST_EN (1ULL << ISCSI_PARAM_DATADGST_EN) +#define ISCSI_INITIAL_R2T_EN (1ULL << ISCSI_PARAM_INITIAL_R2T_EN) +#define ISCSI_MAX_R2T (1ULL << ISCSI_PARAM_MAX_R2T) +#define ISCSI_IMM_DATA_EN (1ULL << ISCSI_PARAM_IMM_DATA_EN) +#define ISCSI_FIRST_BURST (1ULL << ISCSI_PARAM_FIRST_BURST) +#define ISCSI_MAX_BURST (1ULL << ISCSI_PARAM_MAX_BURST) +#define ISCSI_PDU_INORDER_EN (1ULL << ISCSI_PARAM_PDU_INORDER_EN) +#define ISCSI_DATASEQ_INORDER_EN (1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN) +#define ISCSI_ERL (1ULL << ISCSI_PARAM_ERL) +#define ISCSI_IFMARKER_EN (1ULL << ISCSI_PARAM_IFMARKER_EN) +#define ISCSI_OFMARKER_EN (1ULL << ISCSI_PARAM_OFMARKER_EN) +#define ISCSI_EXP_STATSN (1ULL << ISCSI_PARAM_EXP_STATSN) +#define ISCSI_TARGET_NAME (1ULL << ISCSI_PARAM_TARGET_NAME) +#define ISCSI_TPGT (1ULL << ISCSI_PARAM_TPGT) +#define ISCSI_PERSISTENT_ADDRESS (1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS) +#define ISCSI_PERSISTENT_PORT (1ULL << ISCSI_PARAM_PERSISTENT_PORT) +#define ISCSI_SESS_RECOVERY_TMO (1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO) +#define ISCSI_CONN_PORT (1ULL << ISCSI_PARAM_CONN_PORT) +#define ISCSI_CONN_ADDRESS (1ULL << ISCSI_PARAM_CONN_ADDRESS) +#define ISCSI_USERNAME (1ULL << ISCSI_PARAM_USERNAME) +#define ISCSI_USERNAME_IN (1ULL << ISCSI_PARAM_USERNAME_IN) +#define ISCSI_PASSWORD (1ULL << ISCSI_PARAM_PASSWORD) +#define ISCSI_PASSWORD_IN (1ULL << ISCSI_PARAM_PASSWORD_IN) +#define ISCSI_FAST_ABORT (1ULL << ISCSI_PARAM_FAST_ABORT) +#define ISCSI_ABORT_TMO (1ULL << ISCSI_PARAM_ABORT_TMO) +#define ISCSI_LU_RESET_TMO (1ULL << ISCSI_PARAM_LU_RESET_TMO) +#define ISCSI_HOST_RESET_TMO (1ULL << ISCSI_PARAM_HOST_RESET_TMO) +#define ISCSI_PING_TMO (1ULL << ISCSI_PARAM_PING_TMO) +#define ISCSI_RECV_TMO (1ULL << ISCSI_PARAM_RECV_TMO) +#define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME) +#define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) +#define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) + +/* iSCSI HBA params */ +enum iscsi_host_param { + ISCSI_HOST_PARAM_HWADDRESS, + ISCSI_HOST_PARAM_INITIATOR_NAME, + ISCSI_HOST_PARAM_NETDEV_NAME, + ISCSI_HOST_PARAM_IPADDRESS, + ISCSI_HOST_PARAM_MAX, +}; + +#define ISCSI_HOST_HWADDRESS (1ULL << ISCSI_HOST_PARAM_HWADDRESS) +#define ISCSI_HOST_INITIATOR_NAME (1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME) +#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) +#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS) + +#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) +#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) + +/* + * These flags presents iSCSI Data-Path capabilities. + */ +#define CAP_RECOVERY_L0 0x1 +#define CAP_RECOVERY_L1 0x2 +#define CAP_RECOVERY_L2 0x4 +#define CAP_MULTI_R2T 0x8 +#define CAP_HDRDGST 0x10 +#define CAP_DATADGST 0x20 +#define CAP_MULTI_CONN 0x40 +#define CAP_TEXT_NEGO 0x80 +#define CAP_MARKERS 0x100 +#define CAP_FW_DB 0x200 +#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ +#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */ +#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ +#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal, + and verification */ + +/* + * These flags describes reason of stop_conn() call + */ +#define STOP_CONN_TERM 0x1 +#define STOP_CONN_SUSPEND 0x2 +#define STOP_CONN_RECOVER 0x3 + +#define ISCSI_STATS_CUSTOM_MAX 32 +#define ISCSI_STATS_CUSTOM_DESC_MAX 64 +struct iscsi_stats_custom { + char desc[ISCSI_STATS_CUSTOM_DESC_MAX]; + uint64_t value; +}; + +/* + * struct iscsi_stats - iSCSI Statistics (iSCSI MIB) + * + * Note: this structure contains counters collected on per-connection basis. + */ +struct iscsi_stats { + /* octets */ + uint64_t txdata_octets; + uint64_t rxdata_octets; + + /* xmit pdus */ + uint32_t noptx_pdus; + uint32_t scsicmd_pdus; + uint32_t tmfcmd_pdus; + uint32_t login_pdus; + uint32_t text_pdus; + uint32_t dataout_pdus; + uint32_t logout_pdus; + uint32_t snack_pdus; + + /* recv pdus */ + uint32_t noprx_pdus; + uint32_t scsirsp_pdus; + uint32_t tmfrsp_pdus; + uint32_t textrsp_pdus; + uint32_t datain_pdus; + uint32_t logoutrsp_pdus; + uint32_t r2t_pdus; + uint32_t async_pdus; + uint32_t rjt_pdus; + + /* errors */ + uint32_t digest_err; + uint32_t timeout_err; + + /* + * iSCSI Custom Statistics support, i.e. Transport could + * extend existing MIB statistics with its own specific statistics + * up to ISCSI_STATS_CUSTOM_MAX + */ + uint32_t custom_length; + struct iscsi_stats_custom custom[0] + __attribute__ ((aligned (sizeof(uint64_t)))); +}; + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_proto.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_proto.h.svn-base new file mode 100644 index 00000000..f2a2c116 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/iscsi_proto.h.svn-base @@ -0,0 +1,620 @@ +/* + * RFC 3720 (iSCSI) protocol data types + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_PROTO_H +#define ISCSI_PROTO_H + +#include <linux/types.h> +#include <scsi/scsi.h> + +#define ISCSI_DRAFT20_VERSION 0x00 + +/* default iSCSI listen port for incoming connections */ +#define ISCSI_LISTEN_PORT 3260 + +/* Padding word length */ +#define ISCSI_PAD_LEN 4 + +/* + * useful common(control and data pathes) macro + */ +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) +#define hton24(p, v) { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ +} +#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;} + +/* initiator tags; opaque for target */ +typedef uint32_t __bitwise__ itt_t; +/* below makes sense only for initiator that created this tag */ +#define build_itt(itt, age) ((__force itt_t)\ + ((itt) | ((age) << ISCSI_AGE_SHIFT))) +#define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK) +#define RESERVED_ITT ((__force itt_t)0xffffffff) + +/* + * iSCSI Template Message Header + */ +struct iscsi_hdr { + uint8_t opcode; + uint8_t flags; /* Final bit */ + uint8_t rsvd2[2]; + uint8_t hlength; /* AHSs total length */ + uint8_t dlength[3]; /* Data length */ + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag, opaque for target */ + __be32 ttt; /* Target Task Tag */ + __be32 statsn; + __be32 exp_statsn; + __be32 max_statsn; + uint8_t other[12]; +}; + +/************************* RFC 3720 Begin *****************************/ + +#define ISCSI_RESERVED_TAG 0xffffffff + +/* Opcode encoding bits */ +#define ISCSI_OP_RETRY 0x80 +#define ISCSI_OP_IMMEDIATE 0x40 +#define ISCSI_OPCODE_MASK 0x3F + +/* Initiator Opcode values */ +#define ISCSI_OP_NOOP_OUT 0x00 +#define ISCSI_OP_SCSI_CMD 0x01 +#define ISCSI_OP_SCSI_TMFUNC 0x02 +#define ISCSI_OP_LOGIN 0x03 +#define ISCSI_OP_TEXT 0x04 +#define ISCSI_OP_SCSI_DATA_OUT 0x05 +#define ISCSI_OP_LOGOUT 0x06 +#define ISCSI_OP_SNACK 0x10 + +#define ISCSI_OP_VENDOR1_CMD 0x1c +#define ISCSI_OP_VENDOR2_CMD 0x1d +#define ISCSI_OP_VENDOR3_CMD 0x1e +#define ISCSI_OP_VENDOR4_CMD 0x1f + +/* Target Opcode values */ +#define ISCSI_OP_NOOP_IN 0x20 +#define ISCSI_OP_SCSI_CMD_RSP 0x21 +#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22 +#define ISCSI_OP_LOGIN_RSP 0x23 +#define ISCSI_OP_TEXT_RSP 0x24 +#define ISCSI_OP_SCSI_DATA_IN 0x25 +#define ISCSI_OP_LOGOUT_RSP 0x26 +#define ISCSI_OP_R2T 0x31 +#define ISCSI_OP_ASYNC_EVENT 0x32 +#define ISCSI_OP_REJECT 0x3f + +struct iscsi_ahs_hdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t ahspec[5]; +}; + +#define ISCSI_AHSTYPE_CDB 1 +#define ISCSI_AHSTYPE_RLENGTH 2 +#define ISCSI_CDB_SIZE 16 + +/* iSCSI PDU Header */ +struct iscsi_cmd { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 data_length; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t cdb[ISCSI_CDB_SIZE]; /* SCSI Command Block */ + /* Additional Data (Command Dependent) */ +}; + +/* Command PDU flags */ +#define ISCSI_FLAG_CMD_FINAL 0x80 +#define ISCSI_FLAG_CMD_READ 0x40 +#define ISCSI_FLAG_CMD_WRITE 0x20 +#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */ + +/* SCSI Command Attribute values */ +#define ISCSI_ATTR_UNTAGGED 0 +#define ISCSI_ATTR_SIMPLE 1 +#define ISCSI_ATTR_ORDERED 2 +#define ISCSI_ATTR_HEAD_OF_QUEUE 3 +#define ISCSI_ATTR_ACA 4 + +struct iscsi_rlength_ahdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t reserved; + __be32 read_length; +}; + +/* Extended CDB AHS */ +struct iscsi_ecdb_ahdr { + __be16 ahslength; /* CDB length - 15, including reserved byte */ + uint8_t ahstype; + uint8_t reserved; + /* 4-byte aligned extended CDB spillover */ + uint8_t ecdb[SCSI_MAX_VARLEN_CDB_SIZE - ISCSI_CDB_SIZE]; +}; + +/* SCSI Response Header */ +struct iscsi_cmd_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd1; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 exp_datasn; + __be32 bi_residual_count; + __be32 residual_count; + /* Response or Sense Data (optional) */ +}; + +/* Command Response PDU flags */ +#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10 +#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08 +#define ISCSI_FLAG_CMD_OVERFLOW 0x04 +#define ISCSI_FLAG_CMD_UNDERFLOW 0x02 + +/* iSCSI Status values. Valid if Rsp Selector bit is not set */ +#define ISCSI_STATUS_CMD_COMPLETED 0 +#define ISCSI_STATUS_TARGET_FAILURE 1 +#define ISCSI_STATUS_SUBSYS_FAILURE 2 + +/* Asynchronous Event Header */ +struct iscsi_async { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + uint8_t rsvd4[8]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t async_event; + uint8_t async_vcode; + __be16 param1; + __be16 param2; + __be16 param3; + uint8_t rsvd5[4]; +}; + +/* iSCSI Event Codes */ +#define ISCSI_ASYNC_MSG_SCSI_EVENT 0 +#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1 +#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2 +#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3 +#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4 +#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255 + +/* NOP-Out Message */ +struct iscsi_nopout { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* NOP-In Message */ +struct iscsi_nopin { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd4[12]; +}; + +/* SCSI Task Management Message Header */ +struct iscsi_tm { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + itt_t rtt; /* Reference Task Tag */ + __be32 cmdsn; + __be32 exp_statsn; + __be32 refcmdsn; + __be32 exp_datasn; + uint8_t rsvd2[8]; +}; + +#define ISCSI_FLAG_TM_FUNC_MASK 0x7F + +/* Function values */ +#define ISCSI_TM_FUNC_ABORT_TASK 1 +#define ISCSI_TM_FUNC_ABORT_TASK_SET 2 +#define ISCSI_TM_FUNC_CLEAR_ACA 3 +#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4 +#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5 +#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6 +#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7 +#define ISCSI_TM_FUNC_TASK_REASSIGN 8 + +/* SCSI Task Management Response Header */ +struct iscsi_tm_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Response values below */ + uint8_t qualifier; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + itt_t itt; /* Initiator Task Tag */ + itt_t rtt; /* Reference Task Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd3[12]; +}; + +/* Response values */ +#define ISCSI_TMF_RSP_COMPLETE 0x00 +#define ISCSI_TMF_RSP_NO_TASK 0x01 +#define ISCSI_TMF_RSP_NO_LUN 0x02 +#define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03 +#define ISCSI_TMF_RSP_NO_FAILOVER 0x04 +#define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05 +#define ISCSI_TMF_RSP_AUTH_FAILED 0x06 +#define ISCSI_TMF_RSP_REJECTED 0xff + +/* Ready To Transfer Header */ +struct iscsi_r2t_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 r2tsn; + __be32 data_offset; + __be32 data_length; +}; + +/* SCSI Data Hdr */ +struct iscsi_data { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; + __be32 ttt; + __be32 rsvd4; + __be32 exp_statsn; + __be32 rsvd5; + __be32 datasn; + __be32 offset; + __be32 rsvd6; + /* Payload */ +}; + +/* SCSI Data Response Hdr */ +struct iscsi_data_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + __be32 offset; + __be32 residual_count; +}; + +/* Data Response PDU flags */ +#define ISCSI_FLAG_DATA_ACK 0x40 +#define ISCSI_FLAG_DATA_OVERFLOW 0x04 +#define ISCSI_FLAG_DATA_UNDERFLOW 0x02 +#define ISCSI_FLAG_DATA_STATUS 0x01 + +/* Text Header */ +struct iscsi_text { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + itt_t itt; + __be32 ttt; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; + /* Text - key=value pairs */ +}; + +#define ISCSI_FLAG_TEXT_CONTINUE 0x40 + +/* Text Response Header */ +struct iscsi_text_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + itt_t itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd5[12]; + /* Text Response - key:value pairs */ +}; + +/* Login Header */ +struct iscsi_login { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t min_version; /* Min. version supported */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + itt_t itt; /* Initiator Task Tag */ + __be16 cid; + __be16 rsvd3; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; +}; + +/* Login PDU flags */ +#define ISCSI_FLAG_LOGIN_TRANSIT 0x80 +#define ISCSI_FLAG_LOGIN_CONTINUE 0x40 +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */ +#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */ + +#define ISCSI_LOGIN_CURRENT_STAGE(flags) \ + ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) +#define ISCSI_LOGIN_NEXT_STAGE(flags) \ + (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK) + +/* Login Response Header */ +struct iscsi_login_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t active_version; /* Active version */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd3; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t status_class; /* see Login RSP ststus classes below */ + uint8_t status_detail; /* see Login RSP Status details below */ + uint8_t rsvd4[10]; +}; + +/* Login stage (phase) codes for CSG, NSG */ +#define ISCSI_INITIAL_LOGIN_STAGE -1 +#define ISCSI_SECURITY_NEGOTIATION_STAGE 0 +#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1 +#define ISCSI_FULL_FEATURE_PHASE 3 + +/* Login Status response classes */ +#define ISCSI_STATUS_CLS_SUCCESS 0x00 +#define ISCSI_STATUS_CLS_REDIRECT 0x01 +#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02 +#define ISCSI_STATUS_CLS_TARGET_ERR 0x03 + +/* Login Status response detail codes */ +/* Class-0 (Success) */ +#define ISCSI_LOGIN_STATUS_ACCEPT 0x00 + +/* Class-1 (Redirection) */ +#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01 +#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02 + +/* Class-2 (Initiator Error) */ +#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00 +#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01 +#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02 +#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03 +#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04 +#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05 +#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06 +#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07 +#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08 +#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09 +#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a +#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b + +/* Class-3 (Target Error) */ +#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00 +#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01 +#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02 + +/* Logout Header */ +struct iscsi_logout { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + itt_t itt; /* Initiator Task Tag */ + __be16 cid; + uint8_t rsvd3[2]; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* Logout PDU flags */ +#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F + +/* logout reason_code values */ + +#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0 +#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1 +#define ISCSI_LOGOUT_REASON_RECOVERY 2 +#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3 + +/* Logout Response Header */ +struct iscsi_logout_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Logout response values below */ + uint8_t rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd3[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd4; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 rsvd5; + __be16 t2wait; + __be16 t2retain; + __be32 rsvd6; +}; + +/* logout response status values */ + +#define ISCSI_LOGOUT_SUCCESS 0 +#define ISCSI_LOGOUT_CID_NOT_FOUND 1 +#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2 +#define ISCSI_LOGOUT_CLEANUP_FAILED 3 + +/* SNACK Header */ +struct iscsi_snack { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[14]; + itt_t itt; + __be32 begrun; + __be32 runlength; + __be32 exp_statsn; + __be32 rsvd3; + __be32 exp_datasn; + uint8_t rsvd6[8]; +}; + +/* SNACK PDU flags */ +#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */ + +/* Reject Message Header */ +struct iscsi_reject { + uint8_t opcode; + uint8_t flags; + uint8_t reason; + uint8_t rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd3[8]; + __be32 ffffffff; + uint8_t rsvd4[4]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + uint8_t rsvd5[8]; + /* Text - Rejected hdr */ +}; + +/* Reason for Reject */ +#define ISCSI_REASON_CMD_BEFORE_LOGIN 1 +#define ISCSI_REASON_DATA_DIGEST_ERROR 2 +#define ISCSI_REASON_DATA_SNACK_REJECT 3 +#define ISCSI_REASON_PROTOCOL_ERROR 4 +#define ISCSI_REASON_CMD_NOT_SUPPORTED 5 +#define ISCSI_REASON_IMM_CMD_REJECT 6 +#define ISCSI_REASON_TASK_IN_PROGRESS 7 +#define ISCSI_REASON_INVALID_SNACK 8 +#define ISCSI_REASON_BOOKMARK_INVALID 9 +#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10 +#define ISCSI_REASON_NEGOTIATION_RESET 11 + +/* Max. number of Key=Value pairs in a text message */ +#define MAX_KEY_VALUE_PAIRS 8192 + +/* maximum length for text keys/values */ +#define KEY_MAXLEN 64 +#define VALUE_MAXLEN 255 +#define TARGET_NAME_MAXLEN VALUE_MAXLEN + +#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192 +#define ISCSI_MIN_MAX_RECV_SEG_LEN 512 +#define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215 + +#define ISCSI_DEF_FIRST_BURST_LEN 65536 +#define ISCSI_MIN_FIRST_BURST_LEN 512 +#define ISCSI_MAX_FIRST_BURST_LEN 16777215 + +#define ISCSI_DEF_MAX_BURST_LEN 262144 +#define ISCSI_MIN_MAX_BURST_LEN 512 +#define ISCSI_MAX_MAX_BURST_LEN 16777215 + +#define ISCSI_DEF_TIME2WAIT 2 + +/************************* RFC 3720 End *****************************/ + +#endif /* ISCSI_PROTO_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libfc.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libfc.h.svn-base new file mode 100644 index 00000000..a2e126b8 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libfc.h.svn-base @@ -0,0 +1,960 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFC_H_ +#define _LIBFC_H_ + +#include <linux/timer.h> +#include <linux/if.h> + +#include <scsi/scsi_transport.h> +#include <scsi/scsi_transport_fc.h> + +#include <scsi/fc/fc_fcp.h> +#include <scsi/fc/fc_ns.h> +#include <scsi/fc/fc_els.h> +#include <scsi/fc/fc_gs.h> + +#include <scsi/fc_frame.h> + +#define LIBFC_DEBUG + +#ifdef LIBFC_DEBUG +/* Log messages */ +#define FC_DBG(fmt, args...) \ + do { \ + printk(KERN_INFO "%s " fmt, __func__, ##args); \ + } while (0) +#else +#define FC_DBG(fmt, args...) +#endif + +/* + * libfc error codes + */ +#define FC_NO_ERR 0 /* no error */ +#define FC_EX_TIMEOUT 1 /* Exchange timeout */ +#define FC_EX_CLOSED 2 /* Exchange closed */ + +/* some helpful macros */ + +#define ntohll(x) be64_to_cpu(x) +#define htonll(x) cpu_to_be64(x) + +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) + +#define hton24(p, v) do { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ + } while (0) + +/* + * FC HBA status + */ +enum fc_lport_state { + LPORT_ST_NONE = 0, + LPORT_ST_FLOGI, + LPORT_ST_DNS, + LPORT_ST_RPN_ID, + LPORT_ST_RFT_ID, + LPORT_ST_SCR, + LPORT_ST_READY, + LPORT_ST_LOGO, + LPORT_ST_RESET +}; + +enum fc_disc_event { + DISC_EV_NONE = 0, + DISC_EV_SUCCESS, + DISC_EV_FAILED +}; + +enum fc_rport_state { + RPORT_ST_NONE = 0, + RPORT_ST_INIT, /* initialized */ + RPORT_ST_PLOGI, /* waiting for PLOGI completion */ + RPORT_ST_PRLI, /* waiting for PRLI completion */ + RPORT_ST_RTV, /* waiting for RTV completion */ + RPORT_ST_READY, /* ready for use */ + RPORT_ST_LOGO, /* port logout sent */ +}; + +enum fc_rport_trans_state { + FC_PORTSTATE_ROGUE, + FC_PORTSTATE_REAL, +}; + +/** + * struct fc_disc_port - temporary discovery port to hold rport identifiers + * @lp: Fibre Channel host port instance + * @peers: node for list management during discovery and RSCN processing + * @ids: identifiers structure to pass to fc_remote_port_add() + * @rport_work: work struct for starting the rport state machine + */ +struct fc_disc_port { + struct fc_lport *lp; + struct list_head peers; + struct fc_rport_identifiers ids; + struct work_struct rport_work; +}; + +enum fc_rport_event { + RPORT_EV_NONE = 0, + RPORT_EV_CREATED, + RPORT_EV_FAILED, + RPORT_EV_STOP, + RPORT_EV_LOGO +}; + +struct fc_rport_operations { + void (*event_callback)(struct fc_lport *, struct fc_rport *, + enum fc_rport_event); +}; + +/** + * struct fc_rport_libfc_priv - libfc internal information about a remote port + * @local_port: Fibre Channel host port instance + * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges + * @flags: REC and RETRY supported flags + * @max_seq: maximum number of concurrent sequences + * @retries: retry count in current state + * @e_d_tov: error detect timeout value (in msec) + * @r_a_tov: resource allocation timeout value (in msec) + * @rp_mutex: mutex protects rport + * @retry_work: + * @event_callback: Callback for rport READY, FAILED or LOGO + */ +struct fc_rport_libfc_priv { + struct fc_lport *local_port; + enum fc_rport_state rp_state; + u16 flags; + #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) + #define FC_RP_FLAGS_RETRY (1 << 1) + u16 max_seq; + unsigned int retries; + unsigned int e_d_tov; + unsigned int r_a_tov; + enum fc_rport_trans_state trans_state; + struct mutex rp_mutex; + struct delayed_work retry_work; + enum fc_rport_event event; + struct fc_rport_operations *ops; + struct list_head peers; + struct work_struct event_work; +}; + +#define PRIV_TO_RPORT(x) \ + (struct fc_rport *)((void *)x - sizeof(struct fc_rport)); +#define RPORT_TO_PRIV(x) \ + (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport)); + +struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *); + +static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn) +{ + rport->node_name = wwnn; + rport->port_name = wwpn; +} + +/* + * fcoe stats structure + */ +struct fcoe_dev_stats { + u64 SecondsSinceLastReset; + u64 TxFrames; + u64 TxWords; + u64 RxFrames; + u64 RxWords; + u64 ErrorFrames; + u64 DumpedFrames; + u64 LinkFailureCount; + u64 LossOfSignalCount; + u64 InvalidTxWordCount; + u64 InvalidCRCCount; + u64 InputRequests; + u64 OutputRequests; + u64 ControlRequests; + u64 InputMegabytes; + u64 OutputMegabytes; +}; + +/* + * els data is used for passing ELS respone specific + * data to send ELS response mainly using infomation + * in exchange and sequence in EM layer. + */ +struct fc_seq_els_data { + struct fc_frame *fp; + enum fc_els_rjt_reason reason; + enum fc_els_rjt_explan explan; +}; + +/* + * FCP request structure, one for each scsi cmd request + */ +struct fc_fcp_pkt { + /* + * housekeeping stuff + */ + struct fc_lport *lp; /* handle to hba struct */ + u16 state; /* scsi_pkt state state */ + u16 tgt_flags; /* target flags */ + atomic_t ref_cnt; /* fcp pkt ref count */ + spinlock_t scsi_pkt_lock; /* Must be taken before the host lock + * if both are held at the same time */ + /* + * SCSI I/O related stuff + */ + struct scsi_cmnd *cmd; /* scsi command pointer. set/clear + * under host lock */ + struct list_head list; /* tracks queued commands. access under + * host lock */ + /* + * timeout related stuff + */ + struct timer_list timer; /* command timer */ + struct completion tm_done; + int wait_for_comp; + unsigned long start_time; /* start jiffie */ + unsigned long end_time; /* end jiffie */ + unsigned long last_pkt_time; /* jiffies of last frame received */ + + /* + * scsi cmd and data transfer information + */ + u32 data_len; + /* + * transport related veriables + */ + struct fcp_cmnd cdb_cmd; + size_t xfer_len; + u32 xfer_contig_end; /* offset of end of contiguous xfer */ + u16 max_payload; /* max payload size in bytes */ + + /* + * scsi/fcp return status + */ + u32 io_status; /* SCSI result upper 24 bits */ + u8 cdb_status; + u8 status_code; /* FCP I/O status */ + /* bit 3 Underrun bit 2: overrun */ + u8 scsi_comp_flags; + u32 req_flags; /* bit 0: read bit:1 write */ + u32 scsi_resid; /* residule length */ + + struct fc_rport *rport; /* remote port pointer */ + struct fc_seq *seq_ptr; /* current sequence pointer */ + /* + * Error Processing + */ + u8 recov_retry; /* count of recovery retries */ + struct fc_seq *recov_seq; /* sequence for REC or SRR */ +}; + +/* + * Structure and function definitions for managing Fibre Channel Exchanges + * and Sequences + * + * fc_exch holds state for one exchange and links to its active sequence. + * + * fc_seq holds the state for an individual sequence. + */ + +struct fc_exch_mgr; + +/* + * Sequence. + */ +struct fc_seq { + u8 id; /* seq ID */ + u16 ssb_stat; /* status flags for sequence status block */ + u16 cnt; /* frames sent so far on sequence */ + u32 rec_data; /* FC-4 value for REC */ +}; + +#define FC_EX_DONE (1 << 0) /* ep is completed */ +#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */ + +/* + * Exchange. + * + * Locking notes: The ex_lock protects following items: + * state, esb_stat, f_ctl, seq.ssb_stat + * seq_id + * sequence allocation + */ +struct fc_exch { + struct fc_exch_mgr *em; /* exchange manager */ + u32 state; /* internal driver state */ + u16 xid; /* our exchange ID */ + struct list_head ex_list; /* free or busy list linkage */ + spinlock_t ex_lock; /* lock covering exchange state */ + atomic_t ex_refcnt; /* reference counter */ + struct delayed_work timeout_work; /* timer for upper level protocols */ + struct fc_lport *lp; /* fc device instance */ + u16 oxid; /* originator's exchange ID */ + u16 rxid; /* responder's exchange ID */ + u32 oid; /* originator's FCID */ + u32 sid; /* source FCID */ + u32 did; /* destination FCID */ + u32 esb_stat; /* exchange status for ESB */ + u32 r_a_tov; /* r_a_tov from rport (msec) */ + u8 seq_id; /* next sequence ID to use */ + u32 f_ctl; /* F_CTL flags for sequences */ + u8 fh_type; /* frame type */ + enum fc_class class; /* class of service */ + struct fc_seq seq; /* single sequence */ + /* + * Handler for responses to this current exchange. + */ + void (*resp)(struct fc_seq *, struct fc_frame *, void *); + void (*destructor)(struct fc_seq *, void *); + /* + * arg is passed as void pointer to exchange + * resp and destructor handlers + */ + void *arg; +}; +#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) + +struct libfc_function_template { + + /* + * Interface to send a FC frame + * + * STATUS: REQUIRED + */ + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); + + /* + * Interface to send ELS/CT frames + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*elsct_send)(struct fc_lport *lport, + struct fc_rport *rport, + struct fc_frame *fp, + unsigned int op, + void (*resp)(struct fc_seq *, + struct fc_frame *fp, + void *arg), + void *arg, u32 timer_msec); + + /* + * Send the FC frame payload using a new exchange and sequence. + * + * The frame pointer with some of the header's fields must be + * filled before calling exch_seq_send(), those fields are, + * + * - routing control + * - FC port did + * - FC port sid + * - FC header type + * - frame control + * - parameter or relative offset + * + * The exchange response handler is set in this routine to resp() + * function pointer. It can be called in two scenarios: if a timeout + * occurs or if a response frame is received for the exchange. The + * fc_frame pointer in response handler will also indicate timeout + * as error using IS_ERR related macros. + * + * The exchange destructor handler is also set in this routine. + * The destructor handler is invoked by EM layer when exchange + * is about to free, this can be used by caller to free its + * resources along with exchange free. + * + * The arg is passed back to resp and destructor handler. + * + * The timeout value (in msec) for an exchange is set if non zero + * timer_msec argument is specified. The timer is canceled when + * it fires or when the exchange is done. The exchange timeout handler + * is registered by EM layer. + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, unsigned int timer_msec); + + /* + * Send a frame using an existing sequence and exchange. + * + * STATUS: OPTIONAL + */ + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* + * Send an ELS response using infomation from a previous + * exchange and sequence. + * + * STATUS: OPTIONAL + */ + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + + /* + * Abort an exchange and sequence. Generally called because of a + * exchange timeout or an abort from the upper layer. + * + * A timer_msec can be specified for abort timeout, if non-zero + * timer_msec value is specified then exchange resp handler + * will be called with timeout error if no response to abort. + * + * STATUS: OPTIONAL + */ + int (*seq_exch_abort)(const struct fc_seq *req_sp, + unsigned int timer_msec); + + /* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + * + * STATUS: OPTIONAL + */ + void (*exch_done)(struct fc_seq *sp); + + /* + * Assigns a EM and a free XID for an new exchange and then + * allocates a new exchange and sequence pair. + * The fp can be used to determine free XID. + * + * STATUS: OPTIONAL + */ + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); + + /* + * Release previously assigned XID by exch_get API. + * The LLD may implement this if XID is assigned by LLD + * in exch_get(). + * + * STATUS: OPTIONAL + */ + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, + u16 ex_id); + + /* + * Start a new sequence on the same exchange/sequence tuple. + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*seq_start_next)(struct fc_seq *sp); + + /* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + * + * STATUS: OPTIONAL + */ + void (*exch_mgr_reset)(struct fc_lport *, + u32 s_id, u32 d_id); + + /* + * Flush the rport work queue. Generally used before shutdown. + * + * STATUS: OPTIONAL + */ + void (*rport_flush_queue)(void); + + /* + * Receive a frame for a local port. + * + * STATUS: OPTIONAL + */ + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* + * Reset the local port. + * + * STATUS: OPTIONAL + */ + int (*lport_reset)(struct fc_lport *); + + /* + * Create a remote port + */ + struct fc_rport *(*rport_create)(struct fc_disc_port *); + + /* + * Initiates the RP state machine. It is called from the LP module. + * This function will issue the following commands to the N_Port + * identified by the FC ID provided. + * + * - PLOGI + * - PRLI + * - RTV + * + * STATUS: OPTIONAL + */ + int (*rport_login)(struct fc_rport *rport); + + /* + * Logoff, and remove the rport from the transport if + * it had been added. This will send a LOGO to the target. + * + * STATUS: OPTIONAL + */ + int (*rport_logoff)(struct fc_rport *rport); + + /* + * Recieve a request from a remote port. + * + * STATUS: OPTIONAL + */ + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, + struct fc_rport *); + + /* + * lookup an rport by it's port ID. + * + * STATUS: OPTIONAL + */ + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); + + /* + * Send a fcp cmd from fsp pkt. + * Called with the SCSI host lock unlocked and irqs disabled. + * + * The resp handler is called when FCP_RSP received. + * + * STATUS: OPTIONAL + */ + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, + void (*resp)(struct fc_seq *, struct fc_frame *fp, + void *arg)); + + /* + * Cleanup the FCP layer, used durring link down and reset + * + * STATUS: OPTIONAL + */ + void (*fcp_cleanup)(struct fc_lport *lp); + + /* + * Abort all I/O on a local port + * + * STATUS: OPTIONAL + */ + void (*fcp_abort_io)(struct fc_lport *lp); + + /* + * Receive a request for the discovery layer. + * + * STATUS: OPTIONAL + */ + void (*disc_recv_req)(struct fc_seq *, + struct fc_frame *, struct fc_lport *); + + /* + * Start discovery for a local port. + * + * STATUS: OPTIONAL + */ + void (*disc_start)(void (*disc_callback)(struct fc_lport *, + enum fc_disc_event), + struct fc_lport *); + + /* + * Stop discovery for a given lport. This will remove + * all discovered rports + * + * STATUS: OPTIONAL + */ + void (*disc_stop) (struct fc_lport *); + + /* + * Stop discovery for a given lport. This will block + * until all discovered rports are deleted from the + * FC transport class + * + * STATUS: OPTIONAL + */ + void (*disc_stop_final) (struct fc_lport *); +}; + +/* information used by the discovery layer */ +struct fc_disc { + unsigned char retry_count; + unsigned char delay; + unsigned char pending; + unsigned char requested; + unsigned short seq_count; + unsigned char buf_len; + enum fc_disc_event event; + + void (*disc_callback)(struct fc_lport *, + enum fc_disc_event); + + struct list_head rports; + struct fc_lport *lport; + struct mutex disc_mutex; + struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ + struct delayed_work disc_work; +}; + +struct fc_lport { + struct list_head list; + + /* Associations */ + struct Scsi_Host *host; + struct fc_exch_mgr *emp; + struct fc_rport *dns_rp; + struct fc_rport *ptp_rp; + void *scsi_priv; + struct fc_disc disc; + + /* Operational Information */ + struct libfc_function_template tt; + u8 link_up; + u8 qfull; + enum fc_lport_state state; + unsigned long boot_time; + + struct fc_host_statistics host_stats; + struct fcoe_dev_stats *dev_stats[NR_CPUS]; + u64 wwpn; + u64 wwnn; + u8 retry_count; + + /* Capabilities */ + u32 sg_supp:1; /* scatter gather supported */ + u32 seq_offload:1; /* seq offload supported */ + u32 crc_offload:1; /* crc offload supported */ + u32 lro_enabled:1; /* large receive offload */ + u32 mfs; /* max FC payload size */ + unsigned int service_params; + unsigned int e_d_tov; + unsigned int r_a_tov; + u8 max_retry_count; + u16 link_speed; + u16 link_supported_speeds; + u16 lro_xid; /* max xid for fcoe lro */ + struct fc_ns_fts fcts; /* FC-4 type masks */ + struct fc_els_rnid_gen rnid_gen; /* RNID information */ + + /* Semaphores */ + struct mutex lp_mutex; + + /* Miscellaneous */ + struct delayed_work retry_work; + struct delayed_work disc_work; +}; + +/* + * FC_LPORT HELPER FUNCTIONS + *****************************/ +static inline void *lport_priv(const struct fc_lport *lp) +{ + return (void *)(lp + 1); +} + +static inline int fc_lport_test_ready(struct fc_lport *lp) +{ + return lp->state == LPORT_ST_READY; +} + +static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwnn = wwnn; +} + +static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwpn = wwnn; +} + +static inline void fc_lport_state_enter(struct fc_lport *lp, + enum fc_lport_state state) +{ + if (state != lp->state) + lp->retry_count = 0; + lp->state = state; +} + + +/* + * LOCAL PORT LAYER + *****************************/ +int fc_lport_init(struct fc_lport *lp); + +/* + * Destroy the specified local port by finding and freeing all + * fc_rports associated with it and then by freeing the fc_lport + * itself. + */ +int fc_lport_destroy(struct fc_lport *lp); + +/* + * Logout the specified local port from the fabric + */ +int fc_fabric_logoff(struct fc_lport *lp); + +/* + * Initiate the LP state machine. This handler will use fc_host_attr + * to store the FLOGI service parameters, so fc_host_attr must be + * initialized before calling this handler. + */ +int fc_fabric_login(struct fc_lport *lp); + +/* + * The link is up for the given local port. + */ +void fc_linkup(struct fc_lport *); + +/* + * Link is down for the given local port. + */ +void fc_linkdown(struct fc_lport *); + +/* + * Configure the local port. + */ +int fc_lport_config(struct fc_lport *); + +/* + * Reset the local port. + */ +int fc_lport_reset(struct fc_lport *); + +/* + * Set the mfs or reset + */ +int fc_set_mfs(struct fc_lport *lp, u32 mfs); + + +/* + * REMOTE PORT LAYER + *****************************/ +int fc_rport_init(struct fc_lport *lp); +void fc_rport_terminate_io(struct fc_rport *rp); + +/* + * DISCOVERY LAYER + *****************************/ +int fc_disc_init(struct fc_lport *lp); + + +/* + * SCSI LAYER + *****************************/ +/* + * Initialize the SCSI block of libfc + */ +int fc_fcp_init(struct fc_lport *); + +/* + * This section provides an API which allows direct interaction + * with the SCSI-ml. Each of these functions satisfies a function + * pointer defined in Scsi_Host and therefore is always called + * directly from the SCSI-ml. + */ +int fc_queuecommand(struct scsi_cmnd *sc_cmd, + void (*done)(struct scsi_cmnd *)); + +/* + * complete processing of a fcp packet + * + * This function may sleep if a fsp timer is pending. + * The host lock must not be held by caller. + */ +void fc_fcp_complete(struct fc_fcp_pkt *fsp); + +/* + * Send an ABTS frame to the target device. The sc_cmd argument + * is a pointer to the SCSI command to be aborted. + */ +int fc_eh_abort(struct scsi_cmnd *sc_cmd); + +/* + * Reset a LUN by sending send the tm cmd to the target. + */ +int fc_eh_device_reset(struct scsi_cmnd *sc_cmd); + +/* + * Reset the host adapter. + */ +int fc_eh_host_reset(struct scsi_cmnd *sc_cmd); + +/* + * Check rport status. + */ +int fc_slave_alloc(struct scsi_device *sdev); + +/* + * Adjust the queue depth. + */ +int fc_change_queue_depth(struct scsi_device *sdev, int qdepth); + +/* + * Change the tag type. + */ +int fc_change_queue_type(struct scsi_device *sdev, int tag_type); + +/* + * Free memory pools used by the FCP layer. + */ +void fc_fcp_destroy(struct fc_lport *); + +/* + * ELS/CT interface + *****************************/ +/* + * Initializes ELS/CT interface + */ +int fc_elsct_init(struct fc_lport *lp); + + +/* + * EXCHANGE MANAGER LAYER + *****************************/ +/* + * Initializes Exchange Manager related + * function pointers in struct libfc_function_template. + */ +int fc_exch_init(struct fc_lport *lp); + +/* + * Allocates an Exchange Manager (EM). + * + * The EM manages exchanges for their allocation and + * free, also allows exchange lookup for received + * frame. + * + * The class is used for initializing FC class of + * allocated exchange from EM. + * + * The min_xid and max_xid will limit new + * exchange ID (XID) within this range for + * a new exchange. + * The LLD may choose to have multiple EMs, + * e.g. one EM instance per CPU receive thread in LLD. + * The LLD can use exch_get() of struct libfc_function_template + * to specify XID for a new exchange within + * a specified EM instance. + * + * The em_idx to uniquely identify an EM instance. + */ +struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, + enum fc_class class, + u16 min_xid, + u16 max_xid); + +/* + * Free an exchange manager. + */ +void fc_exch_mgr_free(struct fc_exch_mgr *mp); + +/* + * Receive a frame on specified local port and exchange manager. + */ +void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, + struct fc_frame *fp); + +/* + * This function is for exch_seq_send function pointer in + * struct libfc_function_template, see comment block on + * exch_seq_send for description of this function. + */ +struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, u32 timer_msec); + +/* + * send a frame using existing sequence and exchange. + */ +int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); + +/* + * Send ELS response using mainly infomation + * in exchange and sequence in EM layer. + */ +void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + +/* + * This function is for seq_exch_abort function pointer in + * struct libfc_function_template, see comment block on + * seq_exch_abort for description of this function. + */ +int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); + +/* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + */ +void fc_exch_done(struct fc_seq *sp); + +/* + * Assigns a EM and XID for a frame and then allocates + * a new exchange and sequence pair. + * The fp can be used to determine free XID. + */ +struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); + +/* + * Allocate a new exchange and sequence pair. + * if ex_id is zero then next free exchange id + * from specified exchange manger mp will be assigned. + */ +struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, + struct fc_frame *fp, u16 ex_id); +/* + * Start a new sequence on the same exchange as the supplied sequence. + */ +struct fc_seq *fc_seq_start_next(struct fc_seq *sp); + +/* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + */ +void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); + +/* + * Functions for fc_functions_template + */ +void fc_get_host_speed(struct Scsi_Host *shost); +void fc_get_host_port_type(struct Scsi_Host *shost); +void fc_get_host_port_state(struct Scsi_Host *shost); +void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); +struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); + +/* + * module setup functions. + */ +int fc_setup_exch_mgr(void); +void fc_destroy_exch_mgr(void); +int fc_setup_rport(void); +void fc_destroy_rport(void); + +#endif /* _LIBFC_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libfcoe.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libfcoe.h.svn-base new file mode 100644 index 00000000..941818f2 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libfcoe.h.svn-base @@ -0,0 +1,171 @@ +/* + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFCOE_H +#define _LIBFCOE_H + +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <scsi/fc/fc_fcoe.h> +#include <scsi/libfc.h> + +/* + * this percpu struct for fcoe + */ +struct fcoe_percpu_s { + int cpu; + struct task_struct *thread; + struct sk_buff_head fcoe_rx_list; + struct page *crc_eof_page; + int crc_eof_offset; +}; + +/* + * the fcoe sw transport private data + */ +struct fcoe_softc { + struct list_head list; + struct fc_lport *lp; + struct net_device *real_dev; + struct net_device *phys_dev; /* device with ethtool_ops */ + struct packet_type fcoe_packet_type; + struct sk_buff_head fcoe_pending_queue; + u8 fcoe_pending_queue_active; + + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; + u8 data_src_addr[ETH_ALEN]; + /* + * fcoe protocol address learning related stuff + */ + u16 flogi_oxid; + u8 flogi_progress; + u8 address_mode; +}; + +static inline struct net_device *fcoe_netdev( + const struct fc_lport *lp) +{ + return ((struct fcoe_softc *)lport_priv(lp))->real_dev; +} + +static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) +{ + return (struct fcoe_hdr *)skb_network_header(skb); +} + +static inline int skb_fcoe_offset(const struct sk_buff *skb) +{ + return skb_network_offset(skb); +} + +static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) +{ + return (struct fc_frame_header *)skb_transport_header(skb); +} + +static inline int skb_fc_offset(const struct sk_buff *skb) +{ + return skb_transport_offset(skb); +} + +static inline void skb_reset_fc_header(struct sk_buff *skb) +{ + skb_reset_network_header(skb); + skb_set_transport_header(skb, skb_network_offset(skb) + + sizeof(struct fcoe_hdr)); +} + +static inline bool skb_fc_is_data(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; +} + +static inline bool skb_fc_is_cmd(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) +{ + return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); +} + +static inline bool skb_fc_is_roff(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; +} + +static inline u16 skb_fc_oxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); +} + +static inline u16 skb_fc_rxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); +} + +/* FIXME - DMA_BIDIRECTIONAL ? */ +#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0])) +#define skb_cmd(skb) (skb_cb(skb)->fr_cmd) +#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction) +static inline bool skb_fc_is_read(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_FROM_DEVICE; + return false; +} + +static inline bool skb_fc_is_write(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_TO_DEVICE; + return false; +} + +/* libfcoe funcs */ +int fcoe_reset(struct Scsi_Host *shost); +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], + unsigned int scheme, unsigned int port); + +u32 fcoe_fc_crc(struct fc_frame *fp); +int fcoe_xmit(struct fc_lport *, struct fc_frame *); +int fcoe_rcv(struct sk_buff *, struct net_device *, + struct packet_type *, struct net_device *); + +int fcoe_percpu_receive_thread(void *arg); +void fcoe_clean_pending_queue(struct fc_lport *lp); +void fcoe_percpu_clean(struct fc_lport *lp); +void fcoe_watchdog(ulong vp); +int fcoe_link_ok(struct fc_lport *lp); + +struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); +int fcoe_hostlist_add(const struct fc_lport *); +int fcoe_hostlist_remove(const struct fc_lport *); + +struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); +int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); + +/* fcoe sw hba */ +int __init fcoe_sw_init(void); +int __exit fcoe_sw_exit(void); +#endif /* _LIBFCOE_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi.h.svn-base new file mode 100644 index 00000000..7360e191 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi.h.svn-base @@ -0,0 +1,438 @@ +/* + * iSCSI lib definitions + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 - 2006 Mike Christie + * Copyright (C) 2004 - 2005 Dmitry Yusupov + * Copyright (C) 2004 - 2005 Alex Aizman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef LIBISCSI_H +#define LIBISCSI_H + +#include <linux/types.h> +#include <linux/wait.h> +#include <linux/mutex.h> +#include <linux/timer.h> +#include <linux/workqueue.h> +#include <scsi/iscsi_proto.h> +#include <scsi/iscsi_if.h> +#include <scsi/scsi_transport_iscsi.h> + +struct scsi_transport_template; +struct scsi_host_template; +struct scsi_device; +struct Scsi_Host; +struct scsi_cmnd; +struct socket; +struct iscsi_transport; +struct iscsi_cls_session; +struct iscsi_cls_conn; +struct iscsi_session; +struct iscsi_nopin; +struct device; + +/* #define DEBUG_SCSI */ +#ifdef DEBUG_SCSI +#define debug_scsi(fmt...) printk(KERN_INFO "iscsi: " fmt) +#else +#define debug_scsi(fmt...) +#endif + +#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ +#define ISCSI_MGMT_CMDS_MAX 15 + +#define ISCSI_DEF_CMD_PER_LUN 32 +#define ISCSI_MAX_CMD_PER_LUN 128 + +/* Task Mgmt states */ +enum { + TMF_INITIAL, + TMF_QUEUED, + TMF_SUCCESS, + TMF_FAILED, + TMF_TIMEDOUT, + TMF_NOT_FOUND, +}; + +/* Connection suspend "bit" */ +#define ISCSI_SUSPEND_BIT 1 + +#define ISCSI_ITT_MASK 0x1fff +#define ISCSI_TOTAL_CMDS_MAX 4096 +/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ +#define ISCSI_TOTAL_CMDS_MIN 16 +#define ISCSI_AGE_SHIFT 28 +#define ISCSI_AGE_MASK 0xf + +#define ISCSI_ADDRESS_BUF_LEN 64 + +enum { + /* this is the maximum possible storage for AHSs */ + ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) + + sizeof(struct iscsi_rlength_ahdr), + ISCSI_DIGEST_SIZE = sizeof(__u32), +}; + + +enum { + ISCSI_TASK_COMPLETED, + ISCSI_TASK_PENDING, + ISCSI_TASK_RUNNING, +}; + +struct iscsi_r2t_info { + __be32 ttt; /* copied from R2T */ + __be32 exp_statsn; /* copied from R2T */ + uint32_t data_length; /* copied from R2T */ + uint32_t data_offset; /* copied from R2T */ + int data_count; /* DATA-Out payload progress */ + int datasn; + /* LLDs should set/update these values */ + int sent; /* R2T sequence progress */ +}; + +struct iscsi_task { + /* + * Because LLDs allocate their hdr differently, this is a pointer + * and length to that storage. It must be setup at session + * creation time. + */ + struct iscsi_hdr *hdr; + unsigned short hdr_max; + unsigned short hdr_len; /* accumulated size of hdr used */ + /* copied values in case we need to send tmfs */ + itt_t hdr_itt; + __be32 cmdsn; + uint8_t lun[8]; + + int itt; /* this ITT */ + + unsigned imm_count; /* imm-data (bytes) */ + /* offset in unsolicited stream (bytes); */ + struct iscsi_r2t_info unsol_r2t; + char *data; /* mgmt payload */ + unsigned data_count; + struct scsi_cmnd *sc; /* associated SCSI cmd*/ + struct iscsi_conn *conn; /* used connection */ + + /* state set/tested under session->lock */ + int state; + atomic_t refcount; + struct list_head running; /* running cmd list */ + void *dd_data; /* driver/transport data */ +}; + +static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) +{ + return task->unsol_r2t.data_length > task->unsol_r2t.sent; +} + +static inline void* iscsi_next_hdr(struct iscsi_task *task) +{ + return (void*)task->hdr + task->hdr_len; +} + +/* Connection's states */ +enum { + ISCSI_CONN_INITIAL_STAGE, + ISCSI_CONN_STARTED, + ISCSI_CONN_STOPPED, + ISCSI_CONN_CLEANUP_WAIT, +}; + +struct iscsi_conn { + struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ + void *dd_data; /* iscsi_transport data */ + struct iscsi_session *session; /* parent session */ + /* + * conn_stop() flag: stop to recover, stop to terminate + */ + int stop_stage; + struct timer_list transport_timer; + unsigned long last_recv; + unsigned long last_ping; + int ping_timeout; + int recv_timeout; + struct iscsi_task *ping_task; + + /* iSCSI connection-wide sequencing */ + uint32_t exp_statsn; + + /* control data */ + int id; /* CID */ + int c_stage; /* connection state */ + /* + * Preallocated buffer for pdus that have data but do not + * originate from scsi-ml. We never have two pdus using the + * buffer at the same time. It is only allocated to + * the default max recv size because the pdus we support + * should always fit in this buffer + */ + char *data; + struct iscsi_task *login_task; /* mtask used for login/text */ + struct iscsi_task *task; /* xmit task in progress */ + + /* xmit */ + struct list_head mgmtqueue; /* mgmt (control) xmit queue */ + struct list_head mgmt_run_list; /* list of control tasks */ + struct list_head xmitqueue; /* data-path cmd queue */ + struct list_head run_list; /* list of cmds in progress */ + struct list_head requeue; /* tasks needing another run */ + struct work_struct xmitwork; /* per-conn. xmit workqueue */ + unsigned long suspend_tx; /* suspend Tx */ + unsigned long suspend_rx; /* suspend Rx */ + + /* abort */ + wait_queue_head_t ehwait; /* used in eh_abort() */ + struct iscsi_tm tmhdr; + struct timer_list tmf_timer; + int tmf_state; /* see TMF_INITIAL, etc.*/ + + /* negotiated params */ + unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ + unsigned max_xmit_dlength; /* target_max_recv_dsl */ + int hdrdgst_en; + int datadgst_en; + int ifmarker_en; + int ofmarker_en; + /* values userspace uses to id a conn */ + int persistent_port; + char *persistent_address; + /* remote portal currently connected to */ + int portal_port; + char portal_address[ISCSI_ADDRESS_BUF_LEN]; + + /* MIB-statistics */ + uint64_t txdata_octets; + uint64_t rxdata_octets; + uint32_t scsicmd_pdus_cnt; + uint32_t dataout_pdus_cnt; + uint32_t scsirsp_pdus_cnt; + uint32_t datain_pdus_cnt; + uint32_t r2t_pdus_cnt; + uint32_t tmfcmd_pdus_cnt; + int32_t tmfrsp_pdus_cnt; + + /* custom statistics */ + uint32_t eh_abort_cnt; + uint32_t fmr_unalign_cnt; +}; + +struct iscsi_pool { + struct kfifo *queue; /* FIFO Queue */ + void **pool; /* Pool of elements */ + int max; /* Max number of elements */ +}; + +/* Session's states */ +enum { + ISCSI_STATE_FREE = 1, + ISCSI_STATE_LOGGED_IN, + ISCSI_STATE_FAILED, + ISCSI_STATE_TERMINATE, + ISCSI_STATE_IN_RECOVERY, + ISCSI_STATE_RECOVERY_FAILED, + ISCSI_STATE_LOGGING_OUT, +}; + +struct iscsi_session { + struct iscsi_cls_session *cls_session; + /* + * Syncs up the scsi eh thread with the iscsi eh thread when sending + * task management functions. This must be taken before the session + * and recv lock. + */ + struct mutex eh_mutex; + + /* iSCSI session-wide sequencing */ + uint32_t cmdsn; + uint32_t exp_cmdsn; + uint32_t max_cmdsn; + + /* This tracks the reqs queued into the initiator */ + uint32_t queued_cmdsn; + + /* configuration */ + int abort_timeout; + int lu_reset_timeout; + int initial_r2t_en; + unsigned max_r2t; + int imm_data_en; + unsigned first_burst; + unsigned max_burst; + int time2wait; + int time2retain; + int pdu_inorder_en; + int dataseq_inorder_en; + int erl; + int fast_abort; + int tpgt; + char *username; + char *username_in; + char *password; + char *password_in; + char *targetname; + char *ifacename; + char *initiatorname; + /* control data */ + struct iscsi_transport *tt; + struct Scsi_Host *host; + struct iscsi_conn *leadconn; /* leading connection */ + spinlock_t lock; /* protects session state, * + * sequence numbers, * + * session resources: * + * - cmdpool, * + * - mgmtpool, * + * - r2tpool */ + int state; /* session state */ + int age; /* counts session re-opens */ + + int scsi_cmds_max; /* max scsi commands */ + int cmds_max; /* size of cmds array */ + struct iscsi_task **cmds; /* Original Cmds arr */ + struct iscsi_pool cmdpool; /* PDU's pool */ +}; + +enum { + ISCSI_HOST_SETUP, + ISCSI_HOST_REMOVED, +}; + +struct iscsi_host { + char *initiatorname; + /* hw address or netdev iscsi connection is bound to */ + char *hwaddress; + char *netdev; + /* local address */ + int local_port; + char local_address[ISCSI_ADDRESS_BUF_LEN]; + + wait_queue_head_t session_removal_wq; + /* protects sessions and state */ + spinlock_t lock; + int num_sessions; + int state; +}; + +/* + * scsi host template + */ +extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); +extern int iscsi_eh_abort(struct scsi_cmnd *sc); +extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); +extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); +extern int iscsi_queuecommand(struct scsi_cmnd *sc, + void (*done)(struct scsi_cmnd *)); + +/* + * iSCSI host helpers. + */ +#define iscsi_host_priv(_shost) \ + (shost_priv(_shost) + sizeof(struct iscsi_host)) + +extern int iscsi_host_set_param(struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf, + int buflen); +extern int iscsi_host_get_param(struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf); +extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); +extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, + int dd_data_size, uint16_t qdepth); +extern void iscsi_host_remove(struct Scsi_Host *shost); +extern void iscsi_host_free(struct Scsi_Host *shost); + +/* + * session management + */ +extern struct iscsi_cls_session * +iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, + uint16_t, int, uint32_t, unsigned int); +extern void iscsi_session_teardown(struct iscsi_cls_session *); +extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); +extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, + enum iscsi_param param, char *buf, int buflen); +extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, + enum iscsi_param param, char *buf); + +#define iscsi_session_printk(prefix, _sess, fmt, a...) \ + iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) + +/* + * connection management + */ +extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, + int, uint32_t); +extern void iscsi_conn_teardown(struct iscsi_cls_conn *); +extern int iscsi_conn_start(struct iscsi_cls_conn *); +extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); +extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, + int); +extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); +extern void iscsi_session_failure(struct iscsi_cls_session *cls_session, + enum iscsi_err err); +extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, + enum iscsi_param param, char *buf); +extern void iscsi_suspend_tx(struct iscsi_conn *conn); + +#define iscsi_conn_printk(prefix, _c, fmt, a...) \ + iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ + fmt, ##a) + +/* + * pdu and task processing + */ +extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); +extern void iscsi_prep_data_out_pdu(struct iscsi_task *task, + struct iscsi_r2t_info *r2t, + struct iscsi_data *hdr); +extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, + char *, uint32_t); +extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, + char *, int); +extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, + char *, int); +extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); +extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); +extern void iscsi_requeue_task(struct iscsi_task *task); +extern void iscsi_put_task(struct iscsi_task *task); +extern void __iscsi_get_task(struct iscsi_task *task); + +/* + * generic helpers + */ +extern void iscsi_pool_free(struct iscsi_pool *); +extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); + +/* + * inline functions to deal with padding. + */ +static inline unsigned int +iscsi_padded(unsigned int len) +{ + return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1); +} + +static inline unsigned int +iscsi_padding(unsigned int len) +{ + len &= (ISCSI_PAD_LEN - 1); + if (len) + len = ISCSI_PAD_LEN - len; + return len; +} + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi_tcp.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi_tcp.h.svn-base new file mode 100644 index 00000000..9e3182e6 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libiscsi_tcp.h.svn-base @@ -0,0 +1,133 @@ +/* + * iSCSI over TCP/IP Data-Path lib + * + * Copyright (C) 2008 Mike Christie + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef LIBISCSI_TCP_H +#define LIBISCSI_TCP_H + +#include <scsi/libiscsi.h> + +struct iscsi_tcp_conn; +struct iscsi_segment; +struct sk_buff; +struct hash_desc; + +typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, + struct iscsi_segment *); + +struct iscsi_segment { + unsigned char *data; + unsigned int size; + unsigned int copied; + unsigned int total_size; + unsigned int total_copied; + + struct hash_desc *hash; + unsigned char padbuf[ISCSI_PAD_LEN]; + unsigned char recv_digest[ISCSI_DIGEST_SIZE]; + unsigned char digest[ISCSI_DIGEST_SIZE]; + unsigned int digest_len; + + struct scatterlist *sg; + void *sg_mapped; + unsigned int sg_offset; + + iscsi_segment_done_fn_t *done; +}; + +/* Socket connection recieve helper */ +struct iscsi_tcp_recv { + struct iscsi_hdr *hdr; + struct iscsi_segment segment; + + /* Allocate buffer for BHS + AHS */ + uint32_t hdr_buf[64]; + + /* copied and flipped values */ + int datalen; +}; + +struct iscsi_tcp_conn { + struct iscsi_conn *iscsi_conn; + void *dd_data; + int stop_stage; /* conn_stop() flag: * + * stop to recover, * + * stop to terminate */ + /* control data */ + struct iscsi_tcp_recv in; /* TCP receive context */ + /* CRC32C (Rx) LLD should set this is they do not offload */ + struct hash_desc *rx_hash; +}; + +struct iscsi_tcp_task { + uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ + int data_offset; + struct iscsi_r2t_info *r2t; /* in progress solict R2T */ + struct iscsi_pool r2tpool; + struct kfifo *r2tqueue; + void *dd_data; +}; + +enum { + ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ + ISCSI_TCP_SKB_DONE, /* skb is out of data */ + ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ + ISCSI_TCP_SUSPENDED, /* conn is suspended */ +}; + +extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, + unsigned int offset, bool offloaded, int *status); +extern void iscsi_tcp_cleanup_task(struct iscsi_task *task); +extern int iscsi_tcp_task_init(struct iscsi_task *task); +extern int iscsi_tcp_task_xmit(struct iscsi_task *task); + +/* segment helpers */ +extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, + struct iscsi_segment *segment, int recv, + unsigned copied); +extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); + +extern void iscsi_segment_init_linear(struct iscsi_segment *segment, + void *data, size_t size, + iscsi_segment_done_fn_t *done, + struct hash_desc *hash); +extern int +iscsi_segment_seek_sg(struct iscsi_segment *segment, + struct scatterlist *sg_list, unsigned int sg_count, + unsigned int offset, size_t size, + iscsi_segment_done_fn_t *done, struct hash_desc *hash); + +/* digest helpers */ +extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr, + size_t hdrlen, + unsigned char digest[ISCSI_DIGEST_SIZE]); +extern struct iscsi_cls_conn * +iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, + uint32_t conn_idx); +extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); + +/* misc helpers */ +extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); +extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); + +extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, + struct iscsi_stats *stats); +#endif /* LIBISCSI_TCP_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libsas.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libsas.h.svn-base new file mode 100644 index 00000000..e78d3b62 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libsas.h.svn-base @@ -0,0 +1,681 @@ +/* + * SAS host prototypes and structures header file + * + * Copyright (C) 2005 Adaptec, Inc. All rights reserved. + * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> + * + * This file is licensed under GPLv2. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _LIBSAS_H_ +#define _LIBSAS_H_ + + +#include <linux/timer.h> +#include <linux/pci.h> +#include <scsi/sas.h> +#include <linux/libata.h> +#include <linux/list.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_transport_sas.h> +#include <linux/scatterlist.h> + +struct block_device; + +enum sas_class { + SAS, + EXPANDER +}; + +enum sas_phy_role { + PHY_ROLE_NONE = 0, + PHY_ROLE_TARGET = 0x40, + PHY_ROLE_INITIATOR = 0x80, +}; + +enum sas_phy_type { + PHY_TYPE_PHYSICAL, + PHY_TYPE_VIRTUAL +}; + +/* The events are mnemonically described in sas_dump.c + * so when updating/adding events here, please also + * update the other file too. + */ +enum ha_event { + HAE_RESET = 0U, + HA_NUM_EVENTS = 1, +}; + +enum port_event { + PORTE_BYTES_DMAED = 0U, + PORTE_BROADCAST_RCVD = 1, + PORTE_LINK_RESET_ERR = 2, + PORTE_TIMER_EVENT = 3, + PORTE_HARD_RESET = 4, + PORT_NUM_EVENTS = 5, +}; + +enum phy_event { + PHYE_LOSS_OF_SIGNAL = 0U, + PHYE_OOB_DONE = 1, + PHYE_OOB_ERROR = 2, + PHYE_SPINUP_HOLD = 3, /* hot plug SATA, no COMWAKE sent */ + PHY_NUM_EVENTS = 4, +}; + +enum discover_event { + DISCE_DISCOVER_DOMAIN = 0U, + DISCE_REVALIDATE_DOMAIN = 1, + DISCE_PORT_GONE = 2, + DISC_NUM_EVENTS = 3, +}; + +/* ---------- Expander Devices ---------- */ + +#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj) +#define to_dev_attr(_attr) container_of(_attr, struct domain_dev_attribute,\ + attr) + +enum routing_attribute { + DIRECT_ROUTING, + SUBTRACTIVE_ROUTING, + TABLE_ROUTING, +}; + +enum ex_phy_state { + PHY_EMPTY, + PHY_VACANT, + PHY_NOT_PRESENT, + PHY_DEVICE_DISCOVERED +}; + +struct ex_phy { + int phy_id; + + enum ex_phy_state phy_state; + + enum sas_dev_type attached_dev_type; + enum sas_linkrate linkrate; + + u8 attached_sata_host:1; + u8 attached_sata_dev:1; + u8 attached_sata_ps:1; + + enum sas_protocol attached_tproto; + enum sas_protocol attached_iproto; + + u8 attached_sas_addr[SAS_ADDR_SIZE]; + u8 attached_phy_id; + + u8 phy_change_count; + enum routing_attribute routing_attr; + u8 virtual:1; + + int last_da_index; + + struct sas_phy *phy; + struct sas_port *port; +}; + +struct expander_device { + struct list_head children; + + u16 ex_change_count; + u16 max_route_indexes; + u8 num_phys; + u8 configuring:1; + u8 conf_route_table:1; + u8 enclosure_logical_id[8]; + + struct ex_phy *ex_phy; + struct sas_port *parent_port; +}; + +/* ---------- SATA device ---------- */ +enum ata_command_set { + ATA_COMMAND_SET = 0, + ATAPI_COMMAND_SET = 1, +}; + +struct sata_device { + enum ata_command_set command_set; + struct smp_resp rps_resp; /* report_phy_sata_resp */ + __le16 *identify_device; + __le16 *identify_packet_device; + + u8 port_no; /* port number, if this is a PM (Port) */ + struct list_head children; /* PM Ports if this is a PM */ + + struct ata_port *ap; + struct ata_host ata_host; + struct ata_taskfile tf; + u32 sstatus; + u32 serror; + u32 scontrol; +}; + +/* ---------- Domain device ---------- */ +struct domain_device { + enum sas_dev_type dev_type; + + enum sas_linkrate linkrate; + enum sas_linkrate min_linkrate; + enum sas_linkrate max_linkrate; + + int pathways; + + struct domain_device *parent; + struct list_head siblings; /* devices on the same level */ + struct asd_sas_port *port; /* shortcut to root of the tree */ + + struct list_head dev_list_node; + + enum sas_protocol iproto; + enum sas_protocol tproto; + + struct sas_rphy *rphy; + + u8 sas_addr[SAS_ADDR_SIZE]; + u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE]; + + u8 frame_rcvd[32]; + + union { + struct expander_device ex_dev; + struct sata_device sata_dev; /* STP & directly attached */ + }; + + void *lldd_dev; +}; + +struct sas_discovery_event { + struct work_struct work; + struct asd_sas_port *port; +}; + +struct sas_discovery { + spinlock_t disc_event_lock; + struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; + unsigned long pending; + u8 fanout_sas_addr[8]; + u8 eeds_a[8]; + u8 eeds_b[8]; + int max_level; +}; + + +/* The port struct is Class:RW, driver:RO */ +struct asd_sas_port { +/* private: */ + struct completion port_gone_completion; + + struct sas_discovery disc; + struct domain_device *port_dev; + spinlock_t dev_list_lock; + struct list_head dev_list; + enum sas_linkrate linkrate; + + struct sas_phy *phy; + struct work_struct work; + +/* public: */ + int id; + + enum sas_class class; + u8 sas_addr[SAS_ADDR_SIZE]; + u8 attached_sas_addr[SAS_ADDR_SIZE]; + enum sas_protocol iproto; + enum sas_protocol tproto; + + enum sas_oob_mode oob_mode; + + spinlock_t phy_list_lock; + struct list_head phy_list; + int num_phys; + u32 phy_mask; + + struct sas_ha_struct *ha; + + struct sas_port *port; + + void *lldd_port; /* not touched by the sas class code */ +}; + +struct asd_sas_event { + struct work_struct work; + struct asd_sas_phy *phy; +}; + +/* The phy pretty much is controlled by the LLDD. + * The class only reads those fields. + */ +struct asd_sas_phy { +/* private: */ + /* protected by ha->event_lock */ + struct asd_sas_event port_events[PORT_NUM_EVENTS]; + struct asd_sas_event phy_events[PHY_NUM_EVENTS]; + + unsigned long port_events_pending; + unsigned long phy_events_pending; + + int error; + + struct sas_phy *phy; + +/* public: */ + /* The following are class:RO, driver:R/W */ + int enabled; /* must be set */ + + int id; /* must be set */ + enum sas_class class; + enum sas_protocol iproto; + enum sas_protocol tproto; + + enum sas_phy_type type; + enum sas_phy_role role; + enum sas_oob_mode oob_mode; + enum sas_linkrate linkrate; + + u8 *sas_addr; /* must be set */ + u8 attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */ + + spinlock_t frame_rcvd_lock; + u8 *frame_rcvd; /* must be set */ + int frame_rcvd_size; + + spinlock_t sas_prim_lock; + u32 sas_prim; + + struct list_head port_phy_el; /* driver:RO */ + struct asd_sas_port *port; /* Class:RW, driver: RO */ + + struct sas_ha_struct *ha; /* may be set; the class sets it anyway */ + + void *lldd_phy; /* not touched by the sas_class_code */ +}; + +struct scsi_core { + struct Scsi_Host *shost; + + spinlock_t task_queue_lock; + struct list_head task_queue; + int task_queue_size; + + struct task_struct *queue_thread; +}; + +struct sas_ha_event { + struct work_struct work; + struct sas_ha_struct *ha; +}; + +enum sas_ha_state { + SAS_HA_REGISTERED, + SAS_HA_UNREGISTERED +}; + +struct sas_ha_struct { +/* private: */ + spinlock_t event_lock; + struct sas_ha_event ha_events[HA_NUM_EVENTS]; + unsigned long pending; + + enum sas_ha_state state; + spinlock_t state_lock; + + struct scsi_core core; + +/* public: */ + char *sas_ha_name; + struct device *dev; /* should be set */ + struct module *lldd_module; /* should be set */ + + u8 *sas_addr; /* must be set */ + u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE]; + + spinlock_t phy_port_lock; + struct asd_sas_phy **sas_phy; /* array of valid pointers, must be set */ + struct asd_sas_port **sas_port; /* array of valid pointers, must be set */ + int num_phys; /* must be set, gt 0, static */ + + /* The class calls this to send a task for execution. */ + int lldd_max_execute_num; + int lldd_queue_size; + + /* LLDD calls these to notify the class of an event. */ + void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event); + void (*notify_port_event)(struct asd_sas_phy *, enum port_event); + void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event); + + void *lldd_ha; /* not touched by sas class code */ + + struct list_head eh_done_q; +}; + +#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata) + +static inline struct domain_device * +starget_to_domain_dev(struct scsi_target *starget) { + return starget->hostdata; +} + +static inline struct domain_device * +sdev_to_domain_dev(struct scsi_device *sdev) { + return starget_to_domain_dev(sdev->sdev_target); +} + +static inline struct domain_device * +cmd_to_domain_dev(struct scsi_cmnd *cmd) +{ + return sdev_to_domain_dev(cmd->device); +} + +void sas_hash_addr(u8 *hashed, const u8 *sas_addr); + +/* Before calling a notify event, LLDD should use this function + * when the link is severed (possibly from its tasklet). + * The idea is that the Class only reads those, while the LLDD, + * can R/W these (thus avoiding a race). + */ +static inline void sas_phy_disconnected(struct asd_sas_phy *phy) +{ + phy->oob_mode = OOB_NOT_CONNECTED; + phy->linkrate = SAS_LINK_RATE_UNKNOWN; +} + +/* ---------- Tasks ---------- */ +/* + service_response | SAS_TASK_COMPLETE | SAS_TASK_UNDELIVERED | + exec_status | | | + ---------------------+---------------------+-----------------------+ + SAM_... | X | | + DEV_NO_RESPONSE | X | X | + INTERRUPTED | X | | + QUEUE_FULL | | X | + DEVICE_UNKNOWN | | X | + SG_ERR | | X | + ---------------------+---------------------+-----------------------+ + */ + +enum service_response { + SAS_TASK_COMPLETE, + SAS_TASK_UNDELIVERED = -1, +}; + +enum exec_status { + SAM_GOOD = 0, + SAM_CHECK_COND = 2, + SAM_COND_MET = 4, + SAM_BUSY = 8, + SAM_INTERMEDIATE = 0x10, + SAM_IM_COND_MET = 0x12, + SAM_RESV_CONFLICT= 0x14, + SAM_TASK_SET_FULL= 0x28, + SAM_ACA_ACTIVE = 0x30, + SAM_TASK_ABORTED = 0x40, + + SAS_DEV_NO_RESPONSE = 0x80, + SAS_DATA_UNDERRUN, + SAS_DATA_OVERRUN, + SAS_INTERRUPTED, + SAS_QUEUE_FULL, + SAS_DEVICE_UNKNOWN, + SAS_SG_ERR, + SAS_OPEN_REJECT, + SAS_OPEN_TO, + SAS_PROTO_RESPONSE, + SAS_PHY_DOWN, + SAS_NAK_R_ERR, + SAS_PENDING, + SAS_ABORTED_TASK, +}; + +/* When a task finishes with a response, the LLDD examines the + * response: + * - For an ATA task task_status_struct::stat is set to + * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the + * contents of struct ata_task_resp. + * - For SSP tasks, if no data is present or status/TMF response + * is valid, task_status_struct::stat is set. If data is present + * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets + * task_status_struct::buf_valid_size, and task_status_struct::stat is + * set to SAM_CHECK_COND. + * + * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp + * for ATA task. + * + * "frame_len" is the total frame length, which could be more or less + * than actually copied. + * + * Tasks ending with response, always set the residual field. + */ +struct ata_task_resp { + u16 frame_len; + u8 ending_fis[24]; /* dev to host or data-in */ + u32 sstatus; + u32 serror; + u32 scontrol; + u32 sactive; +}; + +#define SAS_STATUS_BUF_SIZE 96 + +struct task_status_struct { + enum service_response resp; + enum exec_status stat; + int buf_valid_size; + + u8 buf[SAS_STATUS_BUF_SIZE]; + + u32 residual; + enum sas_open_rej_reason open_rej_reason; +}; + +/* ATA and ATAPI task queuable to a SAS LLDD. + */ +struct sas_ata_task { + struct host_to_dev_fis fis; + u8 atapi_packet[16]; /* 0 if not ATAPI task */ + + u8 retry_count; /* hardware retry, should be > 0 */ + + u8 dma_xfer:1; /* PIO:0 or DMA:1 */ + u8 use_ncq:1; + u8 set_affil_pol:1; + u8 stp_affil_pol:1; + + u8 device_control_reg_update:1; +}; + +struct sas_smp_task { + struct scatterlist smp_req; + struct scatterlist smp_resp; +}; + +enum task_attribute { + TASK_ATTR_SIMPLE = 0, + TASK_ATTR_HOQ = 1, + TASK_ATTR_ORDERED= 2, + TASK_ATTR_ACA = 4, +}; + +struct sas_ssp_task { + u8 retry_count; /* hardware retry, should be > 0 */ + + u8 LUN[8]; + u8 enable_first_burst:1; + enum task_attribute task_attr; + u8 task_prio; + u8 cdb[16]; +}; + +struct sas_task { + struct domain_device *dev; + struct list_head list; + + spinlock_t task_state_lock; + unsigned task_state_flags; + + enum sas_protocol task_proto; + + /* Used by the discovery code. */ + struct timer_list timer; + struct completion completion; + + union { + struct sas_ata_task ata_task; + struct sas_smp_task smp_task; + struct sas_ssp_task ssp_task; + }; + + struct scatterlist *scatter; + int num_scatter; + u32 total_xfer_len; + u8 data_dir:2; /* Use PCI_DMA_... */ + + struct task_status_struct task_status; + void (*task_done)(struct sas_task *); + + void *lldd_task; /* for use by LLDDs */ + void *uldd_task; + + struct work_struct abort_work; +}; + +extern struct kmem_cache *sas_task_cache; + +#define SAS_TASK_STATE_PENDING 1 +#define SAS_TASK_STATE_DONE 2 +#define SAS_TASK_STATE_ABORTED 4 +#define SAS_TASK_NEED_DEV_RESET 8 +#define SAS_TASK_AT_INITIATOR 16 + +static inline struct sas_task *sas_alloc_task(gfp_t flags) +{ + struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags); + + if (task) { + INIT_LIST_HEAD(&task->list); + spin_lock_init(&task->task_state_lock); + task->task_state_flags = SAS_TASK_STATE_PENDING; + init_timer(&task->timer); + init_completion(&task->completion); + } + + return task; +} + +static inline void sas_free_task(struct sas_task *task) +{ + if (task) { + BUG_ON(!list_empty(&task->list)); + kmem_cache_free(sas_task_cache, task); + } +} + +struct sas_domain_function_template { + /* The class calls these to notify the LLDD of an event. */ + void (*lldd_port_formed)(struct asd_sas_phy *); + void (*lldd_port_deformed)(struct asd_sas_phy *); + + /* The class calls these when a device is found or gone. */ + int (*lldd_dev_found)(struct domain_device *); + void (*lldd_dev_gone)(struct domain_device *); + + int (*lldd_execute_task)(struct sas_task *, int num, + gfp_t gfp_flags); + + /* Task Management Functions. Must be called from process context. */ + int (*lldd_abort_task)(struct sas_task *); + int (*lldd_abort_task_set)(struct domain_device *, u8 *lun); + int (*lldd_clear_aca)(struct domain_device *, u8 *lun); + int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); + int (*lldd_I_T_nexus_reset)(struct domain_device *); + int (*lldd_lu_reset)(struct domain_device *, u8 *lun); + int (*lldd_query_task)(struct sas_task *); + + /* Port and Adapter management */ + int (*lldd_clear_nexus_port)(struct asd_sas_port *); + int (*lldd_clear_nexus_ha)(struct sas_ha_struct *); + + /* Phy management */ + int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *); +}; + +extern int sas_register_ha(struct sas_ha_struct *); +extern int sas_unregister_ha(struct sas_ha_struct *); + +int sas_set_phy_speed(struct sas_phy *phy, + struct sas_phy_linkrates *rates); +int sas_phy_enable(struct sas_phy *phy, int enabled); +int sas_phy_reset(struct sas_phy *phy, int hard_reset); +int sas_queue_up(struct sas_task *task); +extern int sas_queuecommand(struct scsi_cmnd *, + void (*scsi_done)(struct scsi_cmnd *)); +extern int sas_target_alloc(struct scsi_target *); +extern int sas_slave_alloc(struct scsi_device *); +extern int sas_slave_configure(struct scsi_device *); +extern void sas_slave_destroy(struct scsi_device *); +extern int sas_change_queue_depth(struct scsi_device *, int new_depth); +extern int sas_change_queue_type(struct scsi_device *, int qt); +extern int sas_bios_param(struct scsi_device *, + struct block_device *, + sector_t capacity, int *hsc); +extern struct scsi_transport_template * +sas_domain_attach_transport(struct sas_domain_function_template *); +extern void sas_domain_release_transport(struct scsi_transport_template *); + +int sas_discover_root_expander(struct domain_device *); + +void sas_init_ex_attr(void); + +int sas_ex_revalidate_domain(struct domain_device *); + +void sas_unregister_domain_devices(struct asd_sas_port *port); +void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *); +int sas_discover_event(struct asd_sas_port *, enum discover_event ev); + +int sas_discover_sata(struct domain_device *); +int sas_discover_end_dev(struct domain_device *); + +void sas_unregister_dev(struct domain_device *); + +void sas_init_dev(struct domain_device *); + +void sas_task_abort(struct sas_task *); +int __sas_task_abort(struct sas_task *); +int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); +int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); + +extern void sas_target_destroy(struct scsi_target *); +extern int sas_slave_alloc(struct scsi_device *); +extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); + +extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, + struct request *req); + +extern void sas_ssp_task_response(struct device *dev, struct sas_task *task, + struct ssp_response_iu *iu); +struct sas_phy *sas_find_local_phy(struct domain_device *dev); + +int sas_request_addr(struct Scsi_Host *shost, u8 *addr); + +#endif /* _SASLIB_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/libsrp.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/libsrp.h.svn-base new file mode 100644 index 00000000..ba615e4c --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/libsrp.h.svn-base @@ -0,0 +1,77 @@ +#ifndef __LIBSRP_H__ +#define __LIBSRP_H__ + +#include <linux/list.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> +#include <scsi/srp.h> + +enum iue_flags { + V_DIOVER, + V_WRITE, + V_LINKED, + V_FLYING, +}; + +struct srp_buf { + dma_addr_t dma; + void *buf; +}; + +struct srp_queue { + void *pool; + void *items; + struct kfifo *queue; + spinlock_t lock; +}; + +struct srp_target { + struct Scsi_Host *shost; + struct device *dev; + + spinlock_t lock; + struct list_head cmd_queue; + + size_t srp_iu_size; + struct srp_queue iu_queue; + size_t rx_ring_size; + struct srp_buf **rx_ring; + + void *ldata; +}; + +struct iu_entry { + struct srp_target *target; + + struct list_head ilist; + dma_addr_t remote_token; + unsigned long flags; + + struct srp_buf *sbuf; +}; + +typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int, + struct srp_direct_buf *, int, + enum dma_data_direction, unsigned int); +extern int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t); +extern void srp_target_free(struct srp_target *); + +extern struct iu_entry *srp_iu_get(struct srp_target *); +extern void srp_iu_put(struct iu_entry *); + +extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64, u64); +extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, + srp_rdma_t, int, int); + + +static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host) +{ + return (struct srp_target *) host->hostdata; +} + +static inline int srp_cmd_direction(struct srp_cmd *cmd) +{ + return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; +} + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/sas.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/sas.h.svn-base new file mode 100644 index 00000000..e9fd0228 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/sas.h.svn-base @@ -0,0 +1,630 @@ +/* + * SAS structures and definitions header file + * + * Copyright (C) 2005 Adaptec, Inc. All rights reserved. + * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> + * + * This file is licensed under GPLv2. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _SAS_H_ +#define _SAS_H_ + +#include <linux/types.h> +#include <asm/byteorder.h> + +#define SAS_ADDR_SIZE 8 +#define HASHED_SAS_ADDR_SIZE 3 +#define SAS_ADDR(_sa) ((unsigned long long) be64_to_cpu(*(__be64 *)(_sa))) + +#define SMP_REQUEST 0x40 +#define SMP_RESPONSE 0x41 + +#define SSP_DATA 0x01 +#define SSP_XFER_RDY 0x05 +#define SSP_COMMAND 0x06 +#define SSP_RESPONSE 0x07 +#define SSP_TASK 0x16 + +#define SMP_REPORT_GENERAL 0x00 +#define SMP_REPORT_MANUF_INFO 0x01 +#define SMP_READ_GPIO_REG 0x02 +#define SMP_DISCOVER 0x10 +#define SMP_REPORT_PHY_ERR_LOG 0x11 +#define SMP_REPORT_PHY_SATA 0x12 +#define SMP_REPORT_ROUTE_INFO 0x13 +#define SMP_WRITE_GPIO_REG 0x82 +#define SMP_CONF_ROUTE_INFO 0x90 +#define SMP_PHY_CONTROL 0x91 +#define SMP_PHY_TEST_FUNCTION 0x92 + +#define SMP_RESP_FUNC_ACC 0x00 +#define SMP_RESP_FUNC_UNK 0x01 +#define SMP_RESP_FUNC_FAILED 0x02 +#define SMP_RESP_INV_FRM_LEN 0x03 +#define SMP_RESP_NO_PHY 0x10 +#define SMP_RESP_NO_INDEX 0x11 +#define SMP_RESP_PHY_NO_SATA 0x12 +#define SMP_RESP_PHY_UNK_OP 0x13 +#define SMP_RESP_PHY_UNK_TESTF 0x14 +#define SMP_RESP_PHY_TEST_INPROG 0x15 +#define SMP_RESP_PHY_VACANT 0x16 + +/* SAM TMFs */ +#define TMF_ABORT_TASK 0x01 +#define TMF_ABORT_TASK_SET 0x02 +#define TMF_CLEAR_TASK_SET 0x04 +#define TMF_LU_RESET 0x08 +#define TMF_CLEAR_ACA 0x40 +#define TMF_QUERY_TASK 0x80 + +/* SAS TMF responses */ +#define TMF_RESP_FUNC_COMPLETE 0x00 +#define TMF_RESP_INVALID_FRAME 0x02 +#define TMF_RESP_FUNC_ESUPP 0x04 +#define TMF_RESP_FUNC_FAILED 0x05 +#define TMF_RESP_FUNC_SUCC 0x08 +#define TMF_RESP_NO_LUN 0x09 +#define TMF_RESP_OVERLAPPED_TAG 0x0A + +enum sas_oob_mode { + OOB_NOT_CONNECTED, + SATA_OOB_MODE, + SAS_OOB_MODE +}; + +/* See sas_discover.c if you plan on changing these. + */ +enum sas_dev_type { + NO_DEVICE = 0, /* protocol */ + SAS_END_DEV = 1, /* protocol */ + EDGE_DEV = 2, /* protocol */ + FANOUT_DEV = 3, /* protocol */ + SAS_HA = 4, + SATA_DEV = 5, + SATA_PM = 7, + SATA_PM_PORT= 8, +}; + +enum sas_protocol { + SAS_PROTOCOL_SATA = 0x01, + SAS_PROTOCOL_SMP = 0x02, + SAS_PROTOCOL_STP = 0x04, + SAS_PROTOCOL_SSP = 0x08, + SAS_PROTOCOL_ALL = 0x0E, +}; + +/* From the spec; local phys only */ +enum phy_func { + PHY_FUNC_NOP, + PHY_FUNC_LINK_RESET, /* Enables the phy */ + PHY_FUNC_HARD_RESET, + PHY_FUNC_DISABLE, + PHY_FUNC_CLEAR_ERROR_LOG = 5, + PHY_FUNC_CLEAR_AFFIL, + PHY_FUNC_TX_SATA_PS_SIGNAL, + PHY_FUNC_RELEASE_SPINUP_HOLD = 0x10, /* LOCAL PORT ONLY! */ + PHY_FUNC_SET_LINK_RATE, +}; + +/* SAS LLDD would need to report only _very_few_ of those, like BROADCAST. + * Most of those are here for completeness. + */ +enum sas_prim { + SAS_PRIM_AIP_NORMAL = 1, + SAS_PRIM_AIP_R0 = 2, + SAS_PRIM_AIP_R1 = 3, + SAS_PRIM_AIP_R2 = 4, + SAS_PRIM_AIP_WC = 5, + SAS_PRIM_AIP_WD = 6, + SAS_PRIM_AIP_WP = 7, + SAS_PRIM_AIP_RWP = 8, + + SAS_PRIM_BC_CH = 9, + SAS_PRIM_BC_RCH0 = 10, + SAS_PRIM_BC_RCH1 = 11, + SAS_PRIM_BC_R0 = 12, + SAS_PRIM_BC_R1 = 13, + SAS_PRIM_BC_R2 = 14, + SAS_PRIM_BC_R3 = 15, + SAS_PRIM_BC_R4 = 16, + + SAS_PRIM_NOTIFY_ENSP= 17, + SAS_PRIM_NOTIFY_R0 = 18, + SAS_PRIM_NOTIFY_R1 = 19, + SAS_PRIM_NOTIFY_R2 = 20, + + SAS_PRIM_CLOSE_CLAF = 21, + SAS_PRIM_CLOSE_NORM = 22, + SAS_PRIM_CLOSE_R0 = 23, + SAS_PRIM_CLOSE_R1 = 24, + + SAS_PRIM_OPEN_RTRY = 25, + SAS_PRIM_OPEN_RJCT = 26, + SAS_PRIM_OPEN_ACPT = 27, + + SAS_PRIM_DONE = 28, + SAS_PRIM_BREAK = 29, + + SATA_PRIM_DMAT = 33, + SATA_PRIM_PMNAK = 34, + SATA_PRIM_PMACK = 35, + SATA_PRIM_PMREQ_S = 36, + SATA_PRIM_PMREQ_P = 37, + SATA_SATA_R_ERR = 38, +}; + +enum sas_open_rej_reason { + /* Abandon open */ + SAS_OREJ_UNKNOWN = 0, + SAS_OREJ_BAD_DEST = 1, + SAS_OREJ_CONN_RATE = 2, + SAS_OREJ_EPROTO = 3, + SAS_OREJ_RESV_AB0 = 4, + SAS_OREJ_RESV_AB1 = 5, + SAS_OREJ_RESV_AB2 = 6, + SAS_OREJ_RESV_AB3 = 7, + SAS_OREJ_WRONG_DEST= 8, + SAS_OREJ_STP_NORES = 9, + + /* Retry open */ + SAS_OREJ_NO_DEST = 10, + SAS_OREJ_PATH_BLOCKED = 11, + SAS_OREJ_RSVD_CONT0 = 12, + SAS_OREJ_RSVD_CONT1 = 13, + SAS_OREJ_RSVD_INIT0 = 14, + SAS_OREJ_RSVD_INIT1 = 15, + SAS_OREJ_RSVD_STOP0 = 16, + SAS_OREJ_RSVD_STOP1 = 17, + SAS_OREJ_RSVD_RETRY = 18, +}; + +struct dev_to_host_fis { + u8 fis_type; /* 0x34 */ + u8 flags; + u8 status; + u8 error; + + u8 lbal; + union { u8 lbam; u8 byte_count_low; }; + union { u8 lbah; u8 byte_count_high; }; + u8 device; + + u8 lbal_exp; + u8 lbam_exp; + u8 lbah_exp; + u8 _r_a; + + union { u8 sector_count; u8 interrupt_reason; }; + u8 sector_count_exp; + u8 _r_b; + u8 _r_c; + + u32 _r_d; +} __attribute__ ((packed)); + +struct host_to_dev_fis { + u8 fis_type; /* 0x27 */ + u8 flags; + u8 command; + u8 features; + + u8 lbal; + union { u8 lbam; u8 byte_count_low; }; + union { u8 lbah; u8 byte_count_high; }; + u8 device; + + u8 lbal_exp; + u8 lbam_exp; + u8 lbah_exp; + u8 features_exp; + + union { u8 sector_count; u8 interrupt_reason; }; + u8 sector_count_exp; + u8 _r_a; + u8 control; + + u32 _r_b; +} __attribute__ ((packed)); + +/* Prefer to have code clarity over header file clarity. + */ +#ifdef __LITTLE_ENDIAN_BITFIELD +struct sas_identify_frame { + /* Byte 0 */ + u8 frame_type:4; + u8 dev_type:3; + u8 _un0:1; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un20:1; + u8 smp_iport:1; + u8 stp_iport:1; + u8 ssp_iport:1; + u8 _un247:4; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un30:1; + u8 smp_tport:1; + u8 stp_tport:1; + u8 ssp_tport:1; + u8 _un347:4; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; + + __be32 crc; +} __attribute__ ((packed)); + +struct ssp_frame_hdr { + u8 frame_type; + u8 hashed_dest_addr[HASHED_SAS_ADDR_SIZE]; + u8 _r_a; + u8 hashed_src_addr[HASHED_SAS_ADDR_SIZE]; + __be16 _r_b; + + u8 changing_data_ptr:1; + u8 retransmit:1; + u8 retry_data_frames:1; + u8 _r_c:5; + + u8 num_fill_bytes:2; + u8 _r_d:6; + + u32 _r_e; + __be16 tag; + __be16 tptt; + __be32 data_offs; +} __attribute__ ((packed)); + +struct ssp_response_iu { + u8 _r_a[10]; + + u8 datapres:2; + u8 _r_b:6; + + u8 status; + + u32 _r_c; + + __be32 sense_data_len; + __be32 response_data_len; + + u8 resp_data[0]; + u8 sense_data[0]; +} __attribute__ ((packed)); + +/* ---------- SMP ---------- */ + +struct report_general_resp { + __be16 change_count; + __be16 route_indexes; + u8 _r_a; + u8 num_phys; + + u8 conf_route_table:1; + u8 configuring:1; + u8 _r_b:6; + + u8 _r_c; + + u8 enclosure_logical_id[8]; + + u8 _r_d[12]; +} __attribute__ ((packed)); + +struct discover_resp { + u8 _r_a[5]; + + u8 phy_id; + __be16 _r_b; + + u8 _r_c:4; + u8 attached_dev_type:3; + u8 _r_d:1; + + u8 linkrate:4; + u8 _r_e:4; + + u8 attached_sata_host:1; + u8 iproto:3; + u8 _r_f:4; + + u8 attached_sata_dev:1; + u8 tproto:3; + u8 _r_g:3; + u8 attached_sata_ps:1; + + u8 sas_addr[8]; + u8 attached_sas_addr[8]; + u8 attached_phy_id; + + u8 _r_h[7]; + + u8 hmin_linkrate:4; + u8 pmin_linkrate:4; + u8 hmax_linkrate:4; + u8 pmax_linkrate:4; + + u8 change_count; + + u8 pptv:4; + u8 _r_i:3; + u8 virtual:1; + + u8 routing_attr:4; + u8 _r_j:4; + + u8 conn_type; + u8 conn_el_index; + u8 conn_phy_link; + + u8 _r_k[8]; +} __attribute__ ((packed)); + +struct report_phy_sata_resp { + u8 _r_a[5]; + + u8 phy_id; + u8 _r_b; + + u8 affil_valid:1; + u8 affil_supp:1; + u8 _r_c:6; + + u32 _r_d; + + u8 stp_sas_addr[8]; + + struct dev_to_host_fis fis; + + u32 _r_e; + + u8 affil_stp_ini_addr[8]; + + __be32 crc; +} __attribute__ ((packed)); + +struct smp_resp { + u8 frame_type; + u8 function; + u8 result; + u8 reserved; + union { + struct report_general_resp rg; + struct discover_resp disc; + struct report_phy_sata_resp rps; + }; +} __attribute__ ((packed)); + +#elif defined(__BIG_ENDIAN_BITFIELD) +struct sas_identify_frame { + /* Byte 0 */ + u8 _un0:1; + u8 dev_type:3; + u8 frame_type:4; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un247:4; + u8 ssp_iport:1; + u8 stp_iport:1; + u8 smp_iport:1; + u8 _un20:1; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un347:4; + u8 ssp_tport:1; + u8 stp_tport:1; + u8 smp_tport:1; + u8 _un30:1; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; + + __be32 crc; +} __attribute__ ((packed)); + +struct ssp_frame_hdr { + u8 frame_type; + u8 hashed_dest_addr[HASHED_SAS_ADDR_SIZE]; + u8 _r_a; + u8 hashed_src_addr[HASHED_SAS_ADDR_SIZE]; + __be16 _r_b; + + u8 _r_c:5; + u8 retry_data_frames:1; + u8 retransmit:1; + u8 changing_data_ptr:1; + + u8 _r_d:6; + u8 num_fill_bytes:2; + + u32 _r_e; + __be16 tag; + __be16 tptt; + __be32 data_offs; +} __attribute__ ((packed)); + +struct ssp_response_iu { + u8 _r_a[10]; + + u8 _r_b:6; + u8 datapres:2; + + u8 status; + + u32 _r_c; + + __be32 sense_data_len; + __be32 response_data_len; + + u8 resp_data[0]; + u8 sense_data[0]; +} __attribute__ ((packed)); + +/* ---------- SMP ---------- */ + +struct report_general_resp { + __be16 change_count; + __be16 route_indexes; + u8 _r_a; + u8 num_phys; + + u8 _r_b:6; + u8 configuring:1; + u8 conf_route_table:1; + + u8 _r_c; + + u8 enclosure_logical_id[8]; + + u8 _r_d[12]; +} __attribute__ ((packed)); + +struct discover_resp { + u8 _r_a[5]; + + u8 phy_id; + __be16 _r_b; + + u8 _r_d:1; + u8 attached_dev_type:3; + u8 _r_c:4; + + u8 _r_e:4; + u8 linkrate:4; + + u8 _r_f:4; + u8 iproto:3; + u8 attached_sata_host:1; + + u8 attached_sata_ps:1; + u8 _r_g:3; + u8 tproto:3; + u8 attached_sata_dev:1; + + u8 sas_addr[8]; + u8 attached_sas_addr[8]; + u8 attached_phy_id; + + u8 _r_h[7]; + + u8 pmin_linkrate:4; + u8 hmin_linkrate:4; + u8 pmax_linkrate:4; + u8 hmax_linkrate:4; + + u8 change_count; + + u8 virtual:1; + u8 _r_i:3; + u8 pptv:4; + + u8 _r_j:4; + u8 routing_attr:4; + + u8 conn_type; + u8 conn_el_index; + u8 conn_phy_link; + + u8 _r_k[8]; +} __attribute__ ((packed)); + +struct report_phy_sata_resp { + u8 _r_a[5]; + + u8 phy_id; + u8 _r_b; + + u8 _r_c:6; + u8 affil_supp:1; + u8 affil_valid:1; + + u32 _r_d; + + u8 stp_sas_addr[8]; + + struct dev_to_host_fis fis; + + u32 _r_e; + + u8 affil_stp_ini_addr[8]; + + __be32 crc; +} __attribute__ ((packed)); + +struct smp_resp { + u8 frame_type; + u8 function; + u8 result; + u8 reserved; + union { + struct report_general_resp rg; + struct discover_resp disc; + struct report_phy_sata_resp rps; + }; +} __attribute__ ((packed)); + +#else +#error "Bitfield order not defined!" +#endif + +#endif /* _SAS_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/sas_ata.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/sas_ata.h.svn-base new file mode 100644 index 00000000..c583193a --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/sas_ata.h.svn-base @@ -0,0 +1,60 @@ +/* + * Support for SATA devices on Serial Attached SCSI (SAS) controllers + * + * Copyright (C) 2006 IBM Corporation + * + * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _SAS_ATA_H_ +#define _SAS_ATA_H_ + +#include <linux/libata.h> +#include <scsi/libsas.h> + +#ifdef CONFIG_SCSI_SAS_ATA + +static inline int dev_is_sata(struct domain_device *dev) +{ + return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA); +} + +int sas_ata_init_host_and_port(struct domain_device *found_dev, + struct scsi_target *starget); + +void sas_ata_task_abort(struct sas_task *task); + +#else + + +static inline int dev_is_sata(struct domain_device *dev) +{ + return 0; +} +static inline int sas_ata_init_host_and_port(struct domain_device *found_dev, + struct scsi_target *starget) +{ + return 0; +} +static inline void sas_ata_task_abort(struct sas_task *task) +{ +} +#endif + +#endif /* _SAS_ATA_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi.h.svn-base new file mode 100644 index 00000000..a1091657 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi.h.svn-base @@ -0,0 +1,536 @@ +/* + * This header file contains public constants and structures used by + * the scsi code for linux. + * + * For documentation on the OPCODES, MESSAGES, and SENSE values, + * please consult the SCSI standard. + */ +#ifndef _SCSI_SCSI_H +#define _SCSI_SCSI_H + +#include <linux/types.h> +#include <scsi/scsi_cmnd.h> + +/* + * The maximum number of SG segments that we will put inside a + * scatterlist (unless chaining is used). Should ideally fit inside a + * single page, to avoid a higher order allocation. We could define this + * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The + * minimum value is 32 + */ +#define SCSI_MAX_SG_SEGMENTS 128 + +/* + * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit + * is totally arbitrary, a setting of 2048 will get you at least 8mb ios. + */ +#ifdef ARCH_HAS_SG_CHAIN +#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048 +#else +#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS +#endif + +/* + * Special value for scanning to specify scanning or rescanning of all + * possible channels, (target) ids, or luns on a given shost. + */ +#define SCAN_WILD_CARD ~0 + +/* + * SCSI opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define INITIALIZE_ELEMENT_STATUS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define POSITION_TO_ELEMENT 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define READ_TOC 0x43 +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 +#define MODE_SELECT_10 0x55 +#define RESERVE_10 0x56 +#define RELEASE_10 0x57 +#define MODE_SENSE_10 0x5a +#define PERSISTENT_RESERVE_IN 0x5e +#define PERSISTENT_RESERVE_OUT 0x5f +#define VARIABLE_LENGTH_CMD 0x7f +#define REPORT_LUNS 0xa0 +#define MAINTENANCE_IN 0xa3 +#define MAINTENANCE_OUT 0xa4 +#define MOVE_MEDIUM 0xa5 +#define EXCHANGE_MEDIUM 0xa6 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define WRITE_VERIFY_12 0xae +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define READ_ELEMENT_STATUS 0xb8 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea +#define READ_16 0x88 +#define WRITE_16 0x8a +#define VERIFY_16 0x8f +#define SERVICE_ACTION_IN 0x9e +/* values for service action in */ +#define SAI_READ_CAPACITY_16 0x10 +/* values for maintenance in */ +#define MI_REPORT_TARGET_PGS 0x0a +/* values for maintenance out */ +#define MO_SET_TARGET_PGS 0x0a + +/* Values for T10/04-262r7 */ +#define ATA_16 0x85 /* 16-byte pass-thru */ +#define ATA_12 0xa1 /* 12-byte pass-thru */ + +/* + * SCSI command lengths + */ + +#define SCSI_MAX_VARLEN_CDB_SIZE 260 + +/* defined in T10 SCSI Primary Commands-2 (SPC2) */ +struct scsi_varlen_cdb_hdr { + u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ + u8 control; + u8 misc[5]; + u8 additional_cdb_length; /* total cdb length - 8 */ + __be16 service_action; + /* service specific data follows */ +}; + +static inline unsigned +scsi_varlen_cdb_length(const void *hdr) +{ + return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; +} + +extern const unsigned char scsi_command_size_tbl[8]; +#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] + +static inline unsigned +scsi_command_size(const unsigned char *cmnd) +{ + return (cmnd[0] == VARIABLE_LENGTH_CMD) ? + scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); +} + +/* + * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft + * T10/1561-D Revision 4 Draft dated 7th November 2002. + */ +#define SAM_STAT_GOOD 0x00 +#define SAM_STAT_CHECK_CONDITION 0x02 +#define SAM_STAT_CONDITION_MET 0x04 +#define SAM_STAT_BUSY 0x08 +#define SAM_STAT_INTERMEDIATE 0x10 +#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 +#define SAM_STAT_RESERVATION_CONFLICT 0x18 +#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ +#define SAM_STAT_TASK_SET_FULL 0x28 +#define SAM_STAT_ACA_ACTIVE 0x30 +#define SAM_STAT_TASK_ABORTED 0x40 + +/** scsi_status_is_good - check the status return. + * + * @status: the status passed up from the driver (including host and + * driver components) + * + * This returns true for known good conditions that may be treated as + * command completed normally + */ +static inline int scsi_status_is_good(int status) +{ + /* + * FIXME: bit0 is listed as reserved in SCSI-2, but is + * significant in SCSI-3. For now, we follow the SCSI-2 + * behaviour and ignore reserved bits. + */ + status &= 0xfe; + return ((status == SAM_STAT_GOOD) || + (status == SAM_STAT_INTERMEDIATE) || + (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || + /* FIXME: this is obsolete in SAM-3 */ + (status == SAM_STAT_COMMAND_TERMINATED)); +} + +/* + * Status codes. These are deprecated as they are shifted 1 bit right + * from those found in the SCSI standards. This causes confusion for + * applications that are ported to several OSes. Prefer SAM Status codes + * above. + */ + +#define GOOD 0x00 +#define CHECK_CONDITION 0x01 +#define CONDITION_GOOD 0x02 +#define BUSY 0x04 +#define INTERMEDIATE_GOOD 0x08 +#define INTERMEDIATE_C_GOOD 0x0a +#define RESERVATION_CONFLICT 0x0c +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 +#define ACA_ACTIVE 0x18 +#define TASK_ABORTED 0x20 + +#define STATUS_MASK 0xfe + +/* + * SENSE KEYS + */ + +#define NO_SENSE 0x00 +#define RECOVERED_ERROR 0x01 +#define NOT_READY 0x02 +#define MEDIUM_ERROR 0x03 +#define HARDWARE_ERROR 0x04 +#define ILLEGAL_REQUEST 0x05 +#define UNIT_ATTENTION 0x06 +#define DATA_PROTECT 0x07 +#define BLANK_CHECK 0x08 +#define COPY_ABORTED 0x0a +#define ABORTED_COMMAND 0x0b +#define VOLUME_OVERFLOW 0x0d +#define MISCOMPARE 0x0e + + +/* + * DEVICE TYPES + * Please keep them in 0x%02x format for $MODALIAS to work + */ + +#define TYPE_DISK 0x00 +#define TYPE_TAPE 0x01 +#define TYPE_PRINTER 0x02 +#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ +#define TYPE_WORM 0x04 /* Treated as ROM by our system */ +#define TYPE_ROM 0x05 +#define TYPE_SCANNER 0x06 +#define TYPE_MOD 0x07 /* Magneto-optical disk - + * - treated as TYPE_DISK */ +#define TYPE_MEDIUM_CHANGER 0x08 +#define TYPE_COMM 0x09 /* Communications device */ +#define TYPE_RAID 0x0c +#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define TYPE_RBC 0x0e +#define TYPE_NO_LUN 0x7f + +/* SCSI protocols; these are taken from SPC-3 section 7.5 */ +enum scsi_protocol { + SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ + SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ + SCSI_PROTOCOL_SSA = 2, /* Serial Storage Architecture - Obsolete */ + SCSI_PROTOCOL_SBP = 3, /* firewire */ + SCSI_PROTOCOL_SRP = 4, /* Infiniband RDMA */ + SCSI_PROTOCOL_ISCSI = 5, + SCSI_PROTOCOL_SAS = 6, + SCSI_PROTOCOL_ADT = 7, /* Media Changers */ + SCSI_PROTOCOL_ATA = 8, + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ +}; + +/* Returns a human-readable name for the device */ +extern const char * scsi_device_type(unsigned type); + +/* + * standard mode-select header prepended to all mode-select commands + */ + +struct ccs_modesel_head { + __u8 _r1; /* reserved */ + __u8 medium; /* device-specific medium type */ + __u8 _r2; /* reserved */ + __u8 block_desc_length; /* block descriptor length */ + __u8 density; /* device-specific density code */ + __u8 number_blocks_hi; /* number of blocks in this block desc */ + __u8 number_blocks_med; + __u8 number_blocks_lo; + __u8 _r3; + __u8 block_length_hi; /* block length for blocks in this desc */ + __u8 block_length_med; + __u8 block_length_lo; +}; + +/* + * ScsiLun: 8 byte LUN. + */ +struct scsi_lun { + __u8 scsi_lun[8]; +}; + +/* + * The Well Known LUNS (SAM-3) in our int representation of a LUN + */ +#define SCSI_W_LUN_BASE 0xc100 +#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1) +#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2) +#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3) + +static inline int scsi_is_wlun(unsigned int lun) +{ + return (lun & 0xff00) == SCSI_W_LUN_BASE; +} + + +/* + * MESSAGE CODES + */ + +#define COMMAND_COMPLETE 0x00 +#define EXTENDED_MESSAGE 0x01 +#define EXTENDED_MODIFY_DATA_POINTER 0x00 +#define EXTENDED_SDTR 0x01 +#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ +#define EXTENDED_WDTR 0x03 +#define EXTENDED_PPR 0x04 +#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05 +#define SAVE_POINTERS 0x02 +#define RESTORE_POINTERS 0x03 +#define DISCONNECT 0x04 +#define INITIATOR_ERROR 0x05 +#define ABORT_TASK_SET 0x06 +#define MESSAGE_REJECT 0x07 +#define NOP 0x08 +#define MSG_PARITY_ERROR 0x09 +#define LINKED_CMD_COMPLETE 0x0a +#define LINKED_FLG_CMD_COMPLETE 0x0b +#define TARGET_RESET 0x0c +#define ABORT_TASK 0x0d +#define CLEAR_TASK_SET 0x0e +#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ +#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ +#define CLEAR_ACA 0x16 +#define LOGICAL_UNIT_RESET 0x17 +#define SIMPLE_QUEUE_TAG 0x20 +#define HEAD_OF_QUEUE_TAG 0x21 +#define ORDERED_QUEUE_TAG 0x22 +#define IGNORE_WIDE_RESIDUE 0x23 +#define ACA 0x24 +#define QAS_REQUEST 0x55 + +/* Old SCSI2 names, don't use in new code */ +#define BUS_DEVICE_RESET TARGET_RESET +#define ABORT ABORT_TASK_SET + +/* + * Host byte codes + */ + +#define DID_OK 0x00 /* NO error */ +#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ +#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ +#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ +#define DID_BAD_TARGET 0x04 /* BAD target. */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody. */ +#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */ +#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */ +#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */ +#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also + * without decrementing the retry count */ +#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution + * and the driver blocked the port to + * recover the link. Transport class will + * retry or fail IO */ +#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */ +#define DRIVER_OK 0x00 /* Driver status */ + +/* + * These indicate the error that occurred, and what is available. + */ + +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 + +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 + +#define SUGGEST_RETRY 0x10 +#define SUGGEST_ABORT 0x20 +#define SUGGEST_REMAP 0x30 +#define SUGGEST_DIE 0x40 +#define SUGGEST_SENSE 0x80 +#define SUGGEST_IS_OK 0xff + +#define DRIVER_MASK 0x0f +#define SUGGEST_MASK 0xf0 + +/* + * Internal return values. + */ + +#define NEEDS_RETRY 0x2001 +#define SUCCESS 0x2002 +#define FAILED 0x2003 +#define QUEUED 0x2004 +#define SOFT_ERROR 0x2005 +#define ADD_TO_MLQUEUE 0x2006 +#define TIMEOUT_ERROR 0x2007 +#define SCSI_RETURN_NOT_HANDLED 0x2008 + +/* + * Midlevel queue return values. + */ +#define SCSI_MLQUEUE_HOST_BUSY 0x1055 +#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 +#define SCSI_MLQUEUE_EH_RETRY 0x1057 +#define SCSI_MLQUEUE_TARGET_BUSY 0x1058 + +/* + * Use these to separate status msg and our bytes + * + * These are set by: + * + * status byte = set from target device + * msg_byte = return status from host adapter itself. + * host_byte = set by low-level driver to indicate status. + * driver_byte = set by mid-level. + */ +#define status_byte(result) (((result) >> 1) & 0x7f) +#define msg_byte(result) (((result) >> 8) & 0xff) +#define host_byte(result) (((result) >> 16) & 0xff) +#define driver_byte(result) (((result) >> 24) & 0xff) +#define suggestion(result) (driver_byte(result) & SUGGEST_MASK) + +static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 8; +} + +static inline void set_host_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 16; +} + +static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 24; +} + + +#define sense_class(sense) (((sense) >> 4) & 0x7) +#define sense_error(sense) ((sense) & 0xf) +#define sense_valid(sense) ((sense) & 0x80); + +/* + * default timeouts +*/ +#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ) +#define START_STOP_TIMEOUT (60 * HZ) +#define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ) +#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ) +#define READ_DEFECT_DATA_TIMEOUT (60 * HZ ) + + +#define IDENTIFY_BASE 0x80 +#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\ + ((can_disconnect) ? 0x40 : 0) |\ + ((lun) & 0x07)) + +/* + * struct scsi_device::scsi_level values. For SCSI devices other than those + * prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1) + * where "resp" is a byte array of the response to an INQUIRY. The scsi_level + * variable is visible to the user via sysfs. + */ + +#define SCSI_UNKNOWN 0 +#define SCSI_1 1 +#define SCSI_1_CCS 2 +#define SCSI_2 3 +#define SCSI_3 4 /* SPC */ +#define SCSI_SPC_2 5 +#define SCSI_SPC_3 6 + +/* + * INQ PERIPHERAL QUALIFIERS + */ +#define SCSI_INQ_PQ_CON 0x00 +#define SCSI_INQ_PQ_NOT_CON 0x01 +#define SCSI_INQ_PQ_NOT_CAP 0x03 + + +/* + * Here are some scsi specific ioctl commands which are sometimes useful. + * + * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395 + */ + +/* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */ +#define SCSI_IOCTL_GET_IDLUN 0x5382 + +/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */ + +/* Used to obtain the host number of a device. */ +#define SCSI_IOCTL_PROBE_HOST 0x5385 + +/* Used to obtain the bus number for a device */ +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 + +/* Used to obtain the PCI location of a device */ +#define SCSI_IOCTL_GET_PCI 0x5387 + +/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */ +static inline __u32 scsi_to_u32(__u8 *ptr) +{ + return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; +} + +#endif /* _SCSI_SCSI_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_cmnd.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_cmnd.h.svn-base new file mode 100644 index 00000000..855bf959 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_cmnd.h.svn-base @@ -0,0 +1,294 @@ +#ifndef _SCSI_SCSI_CMND_H +#define _SCSI_SCSI_CMND_H + +#include <linux/dma-mapping.h> +#include <linux/blkdev.h> +#include <linux/list.h> +#include <linux/types.h> +#include <linux/timer.h> +#include <linux/scatterlist.h> + +struct Scsi_Host; +struct scsi_device; + +/* + * MAX_COMMAND_SIZE is: + * The longest fixed-length SCSI CDB as per the SCSI standard. + * fixed-length means: commands that their size can be determined + * by their opcode and the CDB does not carry a length specifier, (unlike + * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly + * true and the SCSI standard also defines extended commands and + * vendor specific commands that can be bigger than 16 bytes. The kernel + * will support these using the same infrastructure used for VARLEN CDB's. + * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml + * supports without specifying a cmd_len by ULD's + */ +#define MAX_COMMAND_SIZE 16 +#if (MAX_COMMAND_SIZE > BLK_MAX_CDB) +# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB +#endif + +struct scsi_data_buffer { + struct sg_table table; + unsigned length; + int resid; +}; + +/* embedded in scsi_cmnd */ +struct scsi_pointer { + char *ptr; /* data pointer */ + int this_residual; /* left in this buffer */ + struct scatterlist *buffer; /* which buffer */ + int buffers_residual; /* how many buffers left */ + + dma_addr_t dma_handle; + + volatile int Status; + volatile int Message; + volatile int have_data_in; + volatile int sent_command; + volatile int phase; +}; + +struct scsi_cmnd { + struct scsi_device *device; + struct list_head list; /* scsi_cmnd participates in queue lists */ + struct list_head eh_entry; /* entry for the host eh_cmd_q */ + int eh_eflags; /* Used by error handlr */ + + /* + * A SCSI Command is assigned a nonzero serial_number before passed + * to the driver's queue command function. The serial_number is + * cleared when scsi_done is entered indicating that the command + * has been completed. It is a bug for LLDDs to use this number + * for purposes other than printk (and even that is only useful + * for debugging). + */ + unsigned long serial_number; + + /* + * This is set to jiffies as it was when the command was first + * allocated. It is used to time how long the command has + * been outstanding + */ + unsigned long jiffies_at_alloc; + + int retries; + int allowed; + + unsigned char prot_op; + unsigned char prot_type; + + unsigned short cmd_len; + enum dma_data_direction sc_data_direction; + + /* These elements define the operation we are about to perform */ + unsigned char *cmnd; + + + /* These elements define the operation we ultimately want to perform */ + struct scsi_data_buffer sdb; + struct scsi_data_buffer *prot_sdb; + + unsigned underflow; /* Return error if less than + this amount is transferred */ + + unsigned transfersize; /* How much we are guaranteed to + transfer with each SCSI transfer + (ie, between disconnect / + reconnects. Probably == sector + size */ + + struct request *request; /* The command we are + working on */ + +#define SCSI_SENSE_BUFFERSIZE 96 + unsigned char *sense_buffer; + /* obtained by REQUEST SENSE when + * CHECK CONDITION is received on original + * command (auto-sense) */ + + /* Low-level done function - can be used by low-level driver to point + * to completion function. Not used by mid/upper level code. */ + void (*scsi_done) (struct scsi_cmnd *); + + /* + * The following fields can be written to by the host specific code. + * Everything else should be left alone. + */ + struct scsi_pointer SCp; /* Scratchpad used by some host adapters */ + + unsigned char *host_scribble; /* The host adapter is allowed to + * call scsi_malloc and get some memory + * and hang it here. The host adapter + * is also expected to call scsi_free + * to release this memory. (The memory + * obtained by scsi_malloc is guaranteed + * to be at an address < 16Mb). */ + + int result; /* Status code from lower level driver */ + + unsigned char tag; /* SCSI-II queued command tag */ +}; + +extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); +extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); +extern void scsi_put_command(struct scsi_cmnd *); +extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, + struct device *); +extern void scsi_finish_command(struct scsi_cmnd *cmd); + +extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, + size_t *offset, size_t *len); +extern void scsi_kunmap_atomic_sg(void *virt); + +extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask); +extern void scsi_release_buffers(struct scsi_cmnd *cmd); + +extern int scsi_dma_map(struct scsi_cmnd *cmd); +extern void scsi_dma_unmap(struct scsi_cmnd *cmd); + +struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); +void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); + +static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.nents; +} + +static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.sgl; +} + +static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd) +{ + return cmd->sdb.length; +} + +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->sdb.resid = resid; +} + +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->sdb.resid; +} + +#define scsi_for_each_sg(cmd, sg, nseg, __i) \ + for_each_sg(scsi_sglist(cmd), sg, nseg, __i) + +static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd) +{ + return blk_bidi_rq(cmd->request) && + (cmd->request->next_rq->special != NULL); +} + +static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd) +{ + return scsi_bidi_cmnd(cmd) ? + cmd->request->next_rq->special : &cmd->sdb; +} + +static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd) +{ + return &cmd->sdb; +} + +static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, + void *buf, int buflen) +{ + return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); +} + +static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, + void *buf, int buflen) +{ + return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); +} + +/* + * The operations below are hints that tell the controller driver how + * to handle I/Os with DIF or similar types of protection information. + */ +enum scsi_prot_operations { + /* Normal I/O */ + SCSI_PROT_NORMAL = 0, + + /* OS-HBA: Protected, HBA-Target: Unprotected */ + SCSI_PROT_READ_INSERT, + SCSI_PROT_WRITE_STRIP, + + /* OS-HBA: Unprotected, HBA-Target: Protected */ + SCSI_PROT_READ_STRIP, + SCSI_PROT_WRITE_INSERT, + + /* OS-HBA: Protected, HBA-Target: Protected */ + SCSI_PROT_READ_PASS, + SCSI_PROT_WRITE_PASS, + + /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ + SCSI_PROT_READ_CONVERT, + SCSI_PROT_WRITE_CONVERT, +}; + +static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) +{ + scmd->prot_op = op; +} + +static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd) +{ + return scmd->prot_op; +} + +/* + * The controller usually does not know anything about the target it + * is communicating with. However, when DIX is enabled the controller + * must be know target type so it can verify the protection + * information passed along with the I/O. + */ +enum scsi_prot_target_type { + SCSI_PROT_DIF_TYPE0 = 0, + SCSI_PROT_DIF_TYPE1, + SCSI_PROT_DIF_TYPE2, + SCSI_PROT_DIF_TYPE3, +}; + +static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type) +{ + scmd->prot_type = type; +} + +static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) +{ + return scmd->prot_type; +} + +static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) +{ + return scmd->request->sector; +} + +static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0; +} + +static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL; +} + +static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb; +} + +#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ + for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) + +#endif /* _SCSI_SCSI_CMND_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dbg.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dbg.h.svn-base new file mode 100644 index 00000000..e89844cc --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dbg.h.svn-base @@ -0,0 +1,24 @@ +#ifndef _SCSI_SCSI_DBG_H +#define _SCSI_SCSI_DBG_H + +struct scsi_cmnd; +struct scsi_sense_hdr; + +extern void scsi_print_command(struct scsi_cmnd *); +extern void __scsi_print_command(unsigned char *); +extern void scsi_show_extd_sense(unsigned char, unsigned char); +extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); +extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); +extern void scsi_cmd_print_sense_hdr(struct scsi_cmnd *, const char *, + struct scsi_sense_hdr *); +extern void scsi_print_sense(char *, struct scsi_cmnd *); +extern void __scsi_print_sense(const char *name, + const unsigned char *sense_buffer, + int sense_len); +extern void scsi_show_result(int); +extern void scsi_print_result(struct scsi_cmnd *); +extern void scsi_print_status(unsigned char); +extern const char *scsi_sense_key_string(unsigned char); +extern const char *scsi_extd_sense_format(unsigned char, unsigned char); + +#endif /* _SCSI_SCSI_DBG_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_device.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_device.h.svn-base new file mode 100644 index 00000000..01a4c58f --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_device.h.svn-base @@ -0,0 +1,461 @@ +#ifndef _SCSI_SCSI_DEVICE_H +#define _SCSI_SCSI_DEVICE_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/workqueue.h> +#include <linux/blkdev.h> +#include <scsi/scsi.h> +#include <asm/atomic.h> + +struct request_queue; +struct scsi_cmnd; +struct scsi_lun; +struct scsi_sense_hdr; + +struct scsi_mode_data { + __u32 length; + __u16 block_descriptor_length; + __u8 medium_type; + __u8 device_specific; + __u8 header_length; + __u8 longlba:1; +}; + +/* + * sdev state: If you alter this, you also need to alter scsi_sysfs.c + * (for the ascii descriptions) and the state model enforcer: + * scsi_lib:scsi_device_set_state(). + */ +enum scsi_device_state { + SDEV_CREATED = 1, /* device created but not added to sysfs + * Only internal commands allowed (for inq) */ + SDEV_RUNNING, /* device properly configured + * All commands allowed */ + SDEV_CANCEL, /* beginning to delete device + * Only error handler commands allowed */ + SDEV_DEL, /* device deleted + * no commands allowed */ + SDEV_QUIESCE, /* Device quiescent. No block commands + * will be accepted, only specials (which + * originate in the mid-layer) */ + SDEV_OFFLINE, /* Device offlined (by error handling or + * user request */ + SDEV_BLOCK, /* Device blocked by scsi lld. No + * scsi commands from user or midlayer + * should be issued to the scsi + * lld. */ + SDEV_CREATED_BLOCK, /* same as above but for created devices */ +}; + +enum scsi_device_event { + SDEV_EVT_MEDIA_CHANGE = 1, /* media has changed */ + + SDEV_EVT_LAST = SDEV_EVT_MEDIA_CHANGE, + SDEV_EVT_MAXBITS = SDEV_EVT_LAST + 1 +}; + +struct scsi_event { + enum scsi_device_event evt_type; + struct list_head node; + + /* put union of data structures, for non-simple event types, + * here + */ +}; + +struct scsi_device { + struct Scsi_Host *host; + struct request_queue *request_queue; + + /* the next two are protected by the host->host_lock */ + struct list_head siblings; /* list of all devices on this host */ + struct list_head same_target_siblings; /* just the devices sharing same target id */ + + /* this is now protected by the request_queue->queue_lock */ + unsigned int device_busy; /* commands actually active on + * low-level. protected by queue_lock. */ + spinlock_t list_lock; + struct list_head cmd_list; /* queue of in use SCSI Command structures */ + struct list_head starved_entry; + struct scsi_cmnd *current_cmnd; /* currently active command */ + unsigned short queue_depth; /* How deep of a queue we want */ + unsigned short last_queue_full_depth; /* These two are used by */ + unsigned short last_queue_full_count; /* scsi_track_queue_full() */ + unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same + jiffie count on our counter, they + could all be from the same event. */ + + unsigned int id, lun, channel; + + unsigned int manufacturer; /* Manufacturer of device, for using + * vendor-specific cmd's */ + unsigned sector_size; /* size in bytes */ + + void *hostdata; /* available to low-level driver */ + char type; + char scsi_level; + char inq_periph_qual; /* PQ from INQUIRY data */ + unsigned char inquiry_len; /* valid bytes in 'inquiry' */ + unsigned char * inquiry; /* INQUIRY response data */ + const char * vendor; /* [back_compat] point into 'inquiry' ... */ + const char * model; /* ... after scan; point to static string */ + const char * rev; /* ... "nullnullnullnull" before scan */ + unsigned char current_tag; /* current tag */ + struct scsi_target *sdev_target; /* used only for single_lun */ + + unsigned int sdev_bflags; /* black/white flags as also found in + * scsi_devinfo.[hc]. For now used only to + * pass settings from slave_alloc to scsi + * core. */ + unsigned writeable:1; + unsigned removable:1; + unsigned changed:1; /* Data invalid due to media change */ + unsigned busy:1; /* Used to prevent races */ + unsigned lockable:1; /* Able to prevent media removal */ + unsigned locked:1; /* Media removal disabled */ + unsigned borken:1; /* Tell the Seagate driver to be + * painfully slow on this device */ + unsigned disconnect:1; /* can disconnect */ + unsigned soft_reset:1; /* Uses soft reset option */ + unsigned sdtr:1; /* Device supports SDTR messages */ + unsigned wdtr:1; /* Device supports WDTR messages */ + unsigned ppr:1; /* Device supports PPR messages */ + unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */ + unsigned simple_tags:1; /* simple queue tag messages are enabled */ + unsigned ordered_tags:1;/* ordered queue tag messages are enabled */ + unsigned was_reset:1; /* There was a bus reset on the bus for + * this device */ + unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN + * because we did a bus reset. */ + unsigned use_10_for_rw:1; /* first try 10-byte read / write */ + unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ + unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ + unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ + unsigned no_start_on_add:1; /* do not issue start on add */ + unsigned allow_restart:1; /* issue START_UNIT in error handler */ + unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ + unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ + unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ + unsigned select_no_atn:1; + unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ + unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ + unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ + unsigned last_sector_bug:1; /* do not use multisector accesses on + SD_LAST_BUGGY_SECTORS */ + + DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ + struct list_head event_list; /* asserted events */ + struct work_struct event_work; + + unsigned int device_blocked; /* Device returned QUEUE_FULL. */ + + unsigned int max_device_blocked; /* what device_blocked counts down from */ +#define SCSI_DEFAULT_DEVICE_BLOCKED 3 + + atomic_t iorequest_cnt; + atomic_t iodone_cnt; + atomic_t ioerr_cnt; + + struct device sdev_gendev, + sdev_dev; + + struct execute_work ew; /* used to get process context on put */ + + struct scsi_dh_data *scsi_dh_data; + enum scsi_device_state sdev_state; + unsigned long sdev_data[0]; +} __attribute__((aligned(sizeof(unsigned long)))); + +struct scsi_dh_devlist { + char *vendor; + char *model; +}; + +struct scsi_device_handler { + /* Used by the infrastructure */ + struct list_head list; /* list of scsi_device_handlers */ + + /* Filled by the hardware handler */ + struct module *module; + const char *name; + const struct scsi_dh_devlist *devlist; + int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); + int (*attach)(struct scsi_device *); + void (*detach)(struct scsi_device *); + int (*activate)(struct scsi_device *); + int (*prep_fn)(struct scsi_device *, struct request *); +}; + +struct scsi_dh_data { + struct scsi_device_handler *scsi_dh; + char buf[0]; +}; + +#define to_scsi_device(d) \ + container_of(d, struct scsi_device, sdev_gendev) +#define class_to_sdev(d) \ + container_of(d, struct scsi_device, sdev_dev) +#define transport_class_to_sdev(class_dev) \ + to_scsi_device(class_dev->parent) + +#define sdev_printk(prefix, sdev, fmt, a...) \ + dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) + +#define scmd_printk(prefix, scmd, fmt, a...) \ + (scmd)->request->rq_disk ? \ + sdev_printk(prefix, (scmd)->device, "[%s] " fmt, \ + (scmd)->request->rq_disk->disk_name, ##a) : \ + sdev_printk(prefix, (scmd)->device, fmt, ##a) + +enum scsi_target_state { + STARGET_CREATED = 1, + STARGET_RUNNING, + STARGET_DEL, +}; + +/* + * scsi_target: representation of a scsi target, for now, this is only + * used for single_lun devices. If no one has active IO to the target, + * starget_sdev_user is NULL, else it points to the active sdev. + */ +struct scsi_target { + struct scsi_device *starget_sdev_user; + struct list_head siblings; + struct list_head devices; + struct device dev; + unsigned int reap_ref; /* protected by the host lock */ + unsigned int channel; + unsigned int id; /* target id ... replace + * scsi_device.id eventually */ + unsigned int create:1; /* signal that it needs to be added */ + unsigned int single_lun:1; /* Indicates we should only + * allow I/O to one of the luns + * for the device at a time. */ + unsigned int pdt_1f_for_no_lun; /* PDT = 0x1f */ + /* means no lun present */ + /* commands actually active on LLD. protected by host lock. */ + unsigned int target_busy; + /* + * LLDs should set this in the slave_alloc host template callout. + * If set to zero then there is not limit. + */ + unsigned int can_queue; + unsigned int target_blocked; + unsigned int max_target_blocked; +#define SCSI_DEFAULT_TARGET_BLOCKED 3 + + char scsi_level; + struct execute_work ew; + enum scsi_target_state state; + void *hostdata; /* available to low-level driver */ + unsigned long starget_data[0]; /* for the transport */ + /* starget_data must be the last element!!!! */ +} __attribute__((aligned(sizeof(unsigned long)))); + +#define to_scsi_target(d) container_of(d, struct scsi_target, dev) +static inline struct scsi_target *scsi_target(struct scsi_device *sdev) +{ + return to_scsi_target(sdev->sdev_gendev.parent); +} +#define transport_class_to_starget(class_dev) \ + to_scsi_target(class_dev->parent) + +#define starget_printk(prefix, starget, fmt, a...) \ + dev_printk(prefix, &(starget)->dev, fmt, ##a) + +extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, + uint, uint, uint, void *hostdata); +extern int scsi_add_device(struct Scsi_Host *host, uint channel, + uint target, uint lun); +extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh); +extern void scsi_remove_device(struct scsi_device *); +extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); + +extern int scsi_device_get(struct scsi_device *); +extern void scsi_device_put(struct scsi_device *); +extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, + uint, uint, uint); +extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *, + uint, uint, uint); +extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *, + uint); +extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *, + uint); +extern void starget_for_each_device(struct scsi_target *, void *, + void (*fn)(struct scsi_device *, void *)); +extern void __starget_for_each_device(struct scsi_target *, void *, + void (*fn)(struct scsi_device *, + void *)); + +/* only exposed to implement shost_for_each_device */ +extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, + struct scsi_device *); + +/** + * shost_for_each_device - iterate over all devices of a host + * @sdev: the &struct scsi_device to use as a cursor + * @shost: the &struct scsi_host to iterate over + * + * Iterator that returns each device attached to @shost. This loop + * takes a reference on each device and releases it at the end. If + * you break out of the loop, you must call scsi_device_put(sdev). + */ +#define shost_for_each_device(sdev, shost) \ + for ((sdev) = __scsi_iterate_devices((shost), NULL); \ + (sdev); \ + (sdev) = __scsi_iterate_devices((shost), (sdev))) + +/** + * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) + * @sdev: the &struct scsi_device to use as a cursor + * @shost: the &struct scsi_host to iterate over + * + * Iterator that returns each device attached to @shost. It does _not_ + * take a reference on the scsi_device, so the whole loop must be + * protected by shost->host_lock. + * + * Note: The only reason to use this is because you need to access the + * device list in interrupt context. Otherwise you really want to use + * shost_for_each_device instead. + */ +#define __shost_for_each_device(sdev, shost) \ + list_for_each_entry((sdev), &((shost)->__devices), siblings) + +extern void scsi_adjust_queue_depth(struct scsi_device *, int, int); +extern int scsi_track_queue_full(struct scsi_device *, int); + +extern int scsi_set_medium_removal(struct scsi_device *, char); + +extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, + unsigned char *buffer, int len, int timeout, + int retries, struct scsi_mode_data *data, + struct scsi_sense_hdr *); +extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, + int modepage, unsigned char *buffer, int len, + int timeout, int retries, + struct scsi_mode_data *data, + struct scsi_sense_hdr *); +extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, + int retries, struct scsi_sense_hdr *sshdr); +extern int scsi_device_set_state(struct scsi_device *sdev, + enum scsi_device_state state); +extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, + gfp_t gfpflags); +extern void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt); +extern void sdev_evt_send_simple(struct scsi_device *sdev, + enum scsi_device_event evt_type, gfp_t gfpflags); +extern int scsi_device_quiesce(struct scsi_device *sdev); +extern void scsi_device_resume(struct scsi_device *sdev); +extern void scsi_target_quiesce(struct scsi_target *); +extern void scsi_target_resume(struct scsi_target *); +extern void scsi_scan_target(struct device *parent, unsigned int channel, + unsigned int id, unsigned int lun, int rescan); +extern void scsi_target_reap(struct scsi_target *); +extern void scsi_target_block(struct device *); +extern void scsi_target_unblock(struct device *); +extern void scsi_remove_target(struct device *); +extern void int_to_scsilun(unsigned int, struct scsi_lun *); +extern int scsilun_to_int(struct scsi_lun *); +extern const char *scsi_device_state_name(enum scsi_device_state); +extern int scsi_is_sdev_device(const struct device *); +extern int scsi_is_target_device(const struct device *); +extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + unsigned char *sense, int timeout, int retries, + int flag, int *resid); +extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + struct scsi_sense_hdr *, int timeout, int retries, + int *resid); +extern int scsi_execute_async(struct scsi_device *sdev, + const unsigned char *cmd, int cmd_len, int data_direction, + void *buffer, unsigned bufflen, int use_sg, + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); + +static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) +{ + return device_reprobe(&sdev->sdev_gendev); +} + +static inline unsigned int sdev_channel(struct scsi_device *sdev) +{ + return sdev->channel; +} + +static inline unsigned int sdev_id(struct scsi_device *sdev) +{ + return sdev->id; +} + +#define scmd_id(scmd) sdev_id((scmd)->device) +#define scmd_channel(scmd) sdev_channel((scmd)->device) + +/* + * checks for positions of the SCSI state machine + */ +static inline int scsi_device_online(struct scsi_device *sdev) +{ + return sdev->sdev_state != SDEV_OFFLINE; +} +static inline int scsi_device_blocked(struct scsi_device *sdev) +{ + return sdev->sdev_state == SDEV_BLOCK || + sdev->sdev_state == SDEV_CREATED_BLOCK; +} +static inline int scsi_device_created(struct scsi_device *sdev) +{ + return sdev->sdev_state == SDEV_CREATED || + sdev->sdev_state == SDEV_CREATED_BLOCK; +} + +/* accessor functions for the SCSI parameters */ +static inline int scsi_device_sync(struct scsi_device *sdev) +{ + return sdev->sdtr; +} +static inline int scsi_device_wide(struct scsi_device *sdev) +{ + return sdev->wdtr; +} +static inline int scsi_device_dt(struct scsi_device *sdev) +{ + return sdev->ppr; +} +static inline int scsi_device_dt_only(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return (sdev->inquiry[56] & 0x0c) == 0x04; +} +static inline int scsi_device_ius(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return sdev->inquiry[56] & 0x01; +} +static inline int scsi_device_qas(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return sdev->inquiry[56] & 0x02; +} +static inline int scsi_device_enclosure(struct scsi_device *sdev) +{ + return sdev->inquiry[6] & (1<<6); +} + +static inline int scsi_device_protection(struct scsi_device *sdev) +{ + return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0); +} + +#define MODULE_ALIAS_SCSI_DEVICE(type) \ + MODULE_ALIAS("scsi:t-" __stringify(type) "*") +#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" + +#endif /* _SCSI_SCSI_DEVICE_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_devinfo.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_devinfo.h.svn-base new file mode 100644 index 00000000..b4ddd3b1 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_devinfo.h.svn-base @@ -0,0 +1,33 @@ +#ifndef _SCSI_SCSI_DEVINFO_H +#define _SCSI_SCSI_DEVINFO_H +/* + * Flags for SCSI devices that need special treatment + */ +#define BLIST_NOLUN 0x001 /* Only scan LUN 0 */ +#define BLIST_FORCELUN 0x002 /* Known to have LUNs, force scanning, + deprecated: Use max_luns=N */ +#define BLIST_BORKEN 0x004 /* Flag for broken handshaking */ +#define BLIST_KEY 0x008 /* unlock by special command */ +#define BLIST_SINGLELUN 0x010 /* Do not use LUNs in parallel */ +#define BLIST_NOTQ 0x020 /* Buggy Tagged Command Queuing */ +#define BLIST_SPARSELUN 0x040 /* Non consecutive LUN numbering */ +#define BLIST_MAX5LUN 0x080 /* Avoid LUNS >= 5 */ +#define BLIST_ISROM 0x100 /* Treat as (removable) CD-ROM */ +#define BLIST_LARGELUN 0x200 /* LUNs past 7 on a SCSI-2 device */ +#define BLIST_INQUIRY_36 0x400 /* override additional length field */ +#define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */ +#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */ +#define BLIST_MS_SKIP_PAGE_08 0x2000 /* do not send ms page 0x08 */ +#define BLIST_MS_SKIP_PAGE_3F 0x4000 /* do not send ms page 0x3f */ +#define BLIST_USE_10_BYTE_MS 0x8000 /* use 10 byte ms before 6 byte ms */ +#define BLIST_MS_192_BYTES_FOR_3F 0x10000 /* 192 byte ms page 0x3f request */ +#define BLIST_REPORTLUN2 0x20000 /* try REPORT_LUNS even for SCSI-2 devs + (if HBA supports more than 8 LUNs) */ +#define BLIST_NOREPORTLUN 0x40000 /* don't try REPORT_LUNS scan (SCSI-3 devs) */ +#define BLIST_NOT_LOCKABLE 0x80000 /* don't use PREVENT-ALLOW commands */ +#define BLIST_NO_ULD_ATTACH 0x100000 /* device is actually for RAID config */ +#define BLIST_SELECT_NO_ATN 0x200000 /* select without ATN */ +#define BLIST_RETRY_HWERROR 0x400000 /* retry HARDWARE_ERROR */ +#define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */ +#define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dh.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dh.h.svn-base new file mode 100644 index 00000000..33efce20 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_dh.h.svn-base @@ -0,0 +1,80 @@ +/* + * Header file for SCSI device handler infrastruture. + * + * Modified version of patches posted by Mike Christie <michaelc@cs.wisc.edu> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright IBM Corporation, 2007 + * Authors: + * Chandra Seetharaman <sekharan@us.ibm.com> + * Mike Anderson <andmike@linux.vnet.ibm.com> + */ + +#include <scsi/scsi_device.h> + +enum { + SCSI_DH_OK = 0, + /* + * device errors + */ + SCSI_DH_DEV_FAILED, /* generic device error */ + SCSI_DH_DEV_TEMP_BUSY, + SCSI_DH_DEV_UNSUPP, /* device handler not supported */ + SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ + + /* + * transport errors + */ + SCSI_DH_NOTCONN = SCSI_DH_DEVICE_MAX + 1, + SCSI_DH_CONN_FAILURE, + SCSI_DH_TRANSPORT_MAX, /* max transport blkerr definition */ + + /* + * driver and generic errors + */ + SCSI_DH_IO = SCSI_DH_TRANSPORT_MAX + 1, /* generic error */ + SCSI_DH_INVALID_IO, + SCSI_DH_RETRY, /* retry the req, but not immediately */ + SCSI_DH_IMM_RETRY, /* immediately retry the req */ + SCSI_DH_TIMED_OUT, + SCSI_DH_RES_TEMP_UNAVAIL, + SCSI_DH_DEV_OFFLINED, + SCSI_DH_NOSYS, + SCSI_DH_DRIVER_MAX, +}; +#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) +extern int scsi_dh_activate(struct request_queue *); +extern int scsi_dh_handler_exist(const char *); +extern int scsi_dh_attach(struct request_queue *, const char *); +extern void scsi_dh_detach(struct request_queue *); +#else +static inline int scsi_dh_activate(struct request_queue *req) +{ + return 0; +} +static inline int scsi_dh_handler_exist(const char *name) +{ + return 0; +} +static inline int scsi_dh_attach(struct request_queue *req, const char *name) +{ + return SCSI_DH_NOSYS; +} +static inline void scsi_dh_detach(struct request_queue *q) +{ + return; +} +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_driver.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_driver.h.svn-base new file mode 100644 index 00000000..1f5ca7f6 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_driver.h.svn-base @@ -0,0 +1,36 @@ +#ifndef _SCSI_SCSI_DRIVER_H +#define _SCSI_SCSI_DRIVER_H + +#include <linux/device.h> + +struct module; +struct scsi_cmnd; +struct scsi_device; +struct request; +struct request_queue; + + +struct scsi_driver { + struct module *owner; + struct device_driver gendrv; + + void (*rescan)(struct device *); + int (*done)(struct scsi_cmnd *); +}; +#define to_scsi_driver(drv) \ + container_of((drv), struct scsi_driver, gendrv) + +extern int scsi_register_driver(struct device_driver *); +#define scsi_unregister_driver(drv) \ + driver_unregister(drv); + +extern int scsi_register_interface(struct class_interface *); +#define scsi_unregister_interface(intf) \ + class_interface_unregister(intf) + +int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); +int scsi_prep_return(struct request_queue *q, struct request *req, int ret); + +#endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_eh.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_eh.h.svn-base new file mode 100644 index 00000000..06a87908 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_eh.h.svn-base @@ -0,0 +1,95 @@ +#ifndef _SCSI_SCSI_EH_H +#define _SCSI_SCSI_EH_H + +#include <linux/scatterlist.h> + +#include <scsi/scsi_cmnd.h> +struct scsi_device; +struct Scsi_Host; + +/* + * This is a slightly modified SCSI sense "descriptor" format header. + * The addition is to allow the 0x70 and 0x71 response codes. The idea + * is to place the salient data from either "fixed" or "descriptor" sense + * format into one structure to ease application processing. + * + * The original sense buffer should be kept around for those cases + * in which more information is required (e.g. the LBA of a MEDIUM ERROR). + */ +struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ + u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ + u8 sense_key; + u8 asc; + u8 ascq; + u8 byte4; + u8 byte5; + u8 byte6; + u8 additional_length; /* always 0 for fixed sense format */ +}; + +static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) +{ + if (!sshdr) + return 0; + + return (sshdr->response_code & 0x70) == 0x70; +} + + +extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, + struct list_head *done_q); +extern void scsi_eh_flush_done_q(struct list_head *done_q); +extern void scsi_report_bus_reset(struct Scsi_Host *, int); +extern void scsi_report_device_reset(struct Scsi_Host *, int, int); +extern int scsi_block_when_processing_errors(struct scsi_device *); +extern int scsi_normalize_sense(const u8 *sense_buffer, int sb_len, + struct scsi_sense_hdr *sshdr); +extern int scsi_command_normalize_sense(struct scsi_cmnd *cmd, + struct scsi_sense_hdr *sshdr); + +static inline int scsi_sense_is_deferred(struct scsi_sense_hdr *sshdr) +{ + return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); +} + +extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, + int desc_type); + +extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, + u64 * info_out); + +extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); + +/* + * Reset request from external source + */ +#define SCSI_TRY_RESET_DEVICE 1 +#define SCSI_TRY_RESET_BUS 2 +#define SCSI_TRY_RESET_HOST 3 +#define SCSI_TRY_RESET_TARGET 4 + +extern int scsi_reset_provider(struct scsi_device *, int); + +struct scsi_eh_save { + /* saved state */ + int result; + enum dma_data_direction data_direction; + unsigned underflow; + unsigned char cmd_len; + unsigned char prot_op; + unsigned char *cmnd; + struct scsi_data_buffer sdb; + struct request *next_rq; + /* new command support */ + unsigned char eh_cmnd[BLK_MAX_CDB]; + struct scatterlist sense_sgl; +}; + +extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, + struct scsi_eh_save *ses, unsigned char *cmnd, + int cmnd_size, unsigned sense_bytes); + +extern void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, + struct scsi_eh_save *ses); + +#endif /* _SCSI_SCSI_EH_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_host.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_host.h.svn-base new file mode 100644 index 00000000..d123ca84 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_host.h.svn-base @@ -0,0 +1,841 @@ +#ifndef _SCSI_SCSI_HOST_H +#define _SCSI_SCSI_HOST_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/types.h> +#include <linux/workqueue.h> +#include <linux/mutex.h> +#include <scsi/scsi.h> + +struct request_queue; +struct block_device; +struct completion; +struct module; +struct scsi_cmnd; +struct scsi_device; +struct scsi_target; +struct Scsi_Host; +struct scsi_host_cmd_pool; +struct scsi_transport_template; +struct blk_queue_tags; + + +/* + * The various choices mean: + * NONE: Self evident. Host adapter is not capable of scatter-gather. + * ALL: Means that the host adapter module can do scatter-gather, + * and that there is no limit to the size of the table to which + * we scatter/gather data. The value we set here is the maximum + * single element sglist. To use chained sglists, the adapter + * has to set a value beyond ALL (and correctly use the chain + * handling API. + * Anything else: Indicates the maximum number of chains that can be + * used in one scatter-gather request. + */ +#define SG_NONE 0 +#define SG_ALL SCSI_MAX_SG_SEGMENTS + +#define MODE_UNKNOWN 0x00 +#define MODE_INITIATOR 0x01 +#define MODE_TARGET 0x02 + +#define DISABLE_CLUSTERING 0 +#define ENABLE_CLUSTERING 1 + +struct scsi_host_template { + struct module *module; + const char *name; + + /* + * Used to initialize old-style drivers. For new-style drivers + * just perform all work in your module initialization function. + * + * Status: OBSOLETE + */ + int (* detect)(struct scsi_host_template *); + + /* + * Used as unload callback for hosts with old-style drivers. + * + * Status: OBSOLETE + */ + int (* release)(struct Scsi_Host *); + + /* + * The info function will return whatever useful information the + * developer sees fit. If not provided, then the name field will + * be used instead. + * + * Status: OPTIONAL + */ + const char *(* info)(struct Scsi_Host *); + + /* + * Ioctl interface + * + * Status: OPTIONAL + */ + int (* ioctl)(struct scsi_device *dev, int cmd, void __user *arg); + + +#ifdef CONFIG_COMPAT + /* + * Compat handler. Handle 32bit ABI. + * When unknown ioctl is passed return -ENOIOCTLCMD. + * + * Status: OPTIONAL + */ + int (* compat_ioctl)(struct scsi_device *dev, int cmd, void __user *arg); +#endif + + /* + * The queuecommand function is used to queue up a scsi + * command block to the LLDD. When the driver finished + * processing the command the done callback is invoked. + * + * If queuecommand returns 0, then the HBA has accepted the + * command. The done() function must be called on the command + * when the driver has finished with it. (you may call done on the + * command before queuecommand returns, but in this case you + * *must* return 0 from queuecommand). + * + * Queuecommand may also reject the command, in which case it may + * not touch the command and must not call done() for it. + * + * There are two possible rejection returns: + * + * SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but + * allow commands to other devices serviced by this host. + * + * SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this + * host temporarily. + * + * For compatibility, any other non-zero return is treated the + * same as SCSI_MLQUEUE_HOST_BUSY. + * + * NOTE: "temporarily" means either until the next command for# + * this device/host completes, or a period of time determined by + * I/O pressure in the system if there are no other outstanding + * commands. + * + * STATUS: REQUIRED + */ + int (* queuecommand)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + + /* + * The transfer functions are used to queue a scsi command to + * the LLD. When the driver is finished processing the command + * the done callback is invoked. + * + * This is called to inform the LLD to transfer + * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the + * number of scatterlist entried in the command and + * scsi_sglist(cmd) returns the scatterlist. + * + * return values: see queuecommand + * + * If the LLD accepts the cmd, it should set the result to an + * appropriate value when completed before calling the done function. + * + * STATUS: REQUIRED FOR TARGET DRIVERS + */ + /* TODO: rename */ + int (* transfer_response)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + + /* + * This is an error handling strategy routine. You don't need to + * define one of these if you don't want to - there is a default + * routine that is present that should work in most cases. For those + * driver authors that have the inclination and ability to write their + * own strategy routine, this is where it is specified. Note - the + * strategy routine is *ALWAYS* run in the context of the kernel eh + * thread. Thus you are guaranteed to *NOT* be in an interrupt + * handler when you execute this, and you are also guaranteed to + * *NOT* have any other commands being queued while you are in the + * strategy routine. When you return from this function, operations + * return to normal. + * + * See scsi_error.c scsi_unjam_host for additional comments about + * what this function should and should not be attempting to do. + * + * Status: REQUIRED (at least one of them) + */ + int (* eh_abort_handler)(struct scsi_cmnd *); + int (* eh_device_reset_handler)(struct scsi_cmnd *); + int (* eh_target_reset_handler)(struct scsi_cmnd *); + int (* eh_bus_reset_handler)(struct scsi_cmnd *); + int (* eh_host_reset_handler)(struct scsi_cmnd *); + + /* + * Before the mid layer attempts to scan for a new device where none + * currently exists, it will call this entry in your driver. Should + * your driver need to allocate any structs or perform any other init + * items in order to send commands to a currently unused target/lun + * combo, then this is where you can perform those allocations. This + * is specifically so that drivers won't have to perform any kind of + * "is this a new device" checks in their queuecommand routine, + * thereby making the hot path a bit quicker. + * + * Return values: 0 on success, non-0 on failure + * + * Deallocation: If we didn't find any devices at this ID, you will + * get an immediate call to slave_destroy(). If we find something + * here then you will get a call to slave_configure(), then the + * device will be used for however long it is kept around, then when + * the device is removed from the system (or * possibly at reboot + * time), you will then get a call to slave_destroy(). This is + * assuming you implement slave_configure and slave_destroy. + * However, if you allocate memory and hang it off the device struct, + * then you must implement the slave_destroy() routine at a minimum + * in order to avoid leaking memory + * each time a device is tore down. + * + * Status: OPTIONAL + */ + int (* slave_alloc)(struct scsi_device *); + + /* + * Once the device has responded to an INQUIRY and we know the + * device is online, we call into the low level driver with the + * struct scsi_device *. If the low level device driver implements + * this function, it *must* perform the task of setting the queue + * depth on the device. All other tasks are optional and depend + * on what the driver supports and various implementation details. + * + * Things currently recommended to be handled at this time include: + * + * 1. Setting the device queue depth. Proper setting of this is + * described in the comments for scsi_adjust_queue_depth. + * 2. Determining if the device supports the various synchronous + * negotiation protocols. The device struct will already have + * responded to INQUIRY and the results of the standard items + * will have been shoved into the various device flag bits, eg. + * device->sdtr will be true if the device supports SDTR messages. + * 3. Allocating command structs that the device will need. + * 4. Setting the default timeout on this device (if needed). + * 5. Anything else the low level driver might want to do on a device + * specific setup basis... + * 6. Return 0 on success, non-0 on error. The device will be marked + * as offline on error so that no access will occur. If you return + * non-0, your slave_destroy routine will never get called for this + * device, so don't leave any loose memory hanging around, clean + * up after yourself before returning non-0 + * + * Status: OPTIONAL + */ + int (* slave_configure)(struct scsi_device *); + + /* + * Immediately prior to deallocating the device and after all activity + * has ceased the mid layer calls this point so that the low level + * driver may completely detach itself from the scsi device and vice + * versa. The low level driver is responsible for freeing any memory + * it allocated in the slave_alloc or slave_configure calls. + * + * Status: OPTIONAL + */ + void (* slave_destroy)(struct scsi_device *); + + /* + * Before the mid layer attempts to scan for a new device attached + * to a target where no target currently exists, it will call this + * entry in your driver. Should your driver need to allocate any + * structs or perform any other init items in order to send commands + * to a currently unused target, then this is where you can perform + * those allocations. + * + * Return values: 0 on success, non-0 on failure + * + * Status: OPTIONAL + */ + int (* target_alloc)(struct scsi_target *); + + /* + * Immediately prior to deallocating the target structure, and + * after all activity to attached scsi devices has ceased, the + * midlayer calls this point so that the driver may deallocate + * and terminate any references to the target. + * + * Status: OPTIONAL + */ + void (* target_destroy)(struct scsi_target *); + + /* + * If a host has the ability to discover targets on its own instead + * of scanning the entire bus, it can fill in this function and + * call scsi_scan_host(). This function will be called periodically + * until it returns 1 with the scsi_host and the elapsed time of + * the scan in jiffies. + * + * Status: OPTIONAL + */ + int (* scan_finished)(struct Scsi_Host *, unsigned long); + + /* + * If the host wants to be called before the scan starts, but + * after the midlayer has set up ready for the scan, it can fill + * in this function. + * + * Status: OPTIONAL + */ + void (* scan_start)(struct Scsi_Host *); + + /* + * Fill in this function to allow the queue depth of this host + * to be changeable (on a per device basis). Returns either + * the current queue depth setting (may be different from what + * was passed in) or an error. An error should only be + * returned if the requested depth is legal but the driver was + * unable to set it. If the requested depth is illegal, the + * driver should set and return the closest legal queue depth. + * + * Status: OPTIONAL + */ + int (* change_queue_depth)(struct scsi_device *, int); + + /* + * Fill in this function to allow the changing of tag types + * (this also allows the enabling/disabling of tag command + * queueing). An error should only be returned if something + * went wrong in the driver while trying to set the tag type. + * If the driver doesn't support the requested tag type, then + * it should set the closest type it does support without + * returning an error. Returns the actual tag type set. + * + * Status: OPTIONAL + */ + int (* change_queue_type)(struct scsi_device *, int); + + /* + * This function determines the BIOS parameters for a given + * harddisk. These tend to be numbers that are made up by + * the host adapter. Parameters: + * size, device, list (heads, sectors, cylinders) + * + * Status: OPTIONAL + */ + int (* bios_param)(struct scsi_device *, struct block_device *, + sector_t, int []); + + /* + * Can be used to export driver statistics and other infos to the + * world outside the kernel ie. userspace and it also provides an + * interface to feed the driver with information. + * + * Status: OBSOLETE + */ + int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int); + + /* + * This is an optional routine that allows the transport to become + * involved when a scsi io timer fires. The return value tells the + * timer routine how to finish the io timeout handling: + * EH_HANDLED: I fixed the error, please complete the command + * EH_RESET_TIMER: I need more time, reset the timer and + * begin counting again + * EH_NOT_HANDLED Begin normal error recovery + * + * Status: OPTIONAL + */ + enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); + + /* + * Name of proc directory + */ + const char *proc_name; + + /* + * Used to store the procfs directory if a driver implements the + * proc_info method. + */ + struct proc_dir_entry *proc_dir; + + /* + * This determines if we will use a non-interrupt driven + * or an interrupt driven scheme. It is set to the maximum number + * of simultaneous commands a given host adapter will accept. + */ + int can_queue; + + /* + * In many instances, especially where disconnect / reconnect are + * supported, our host also has an ID on the SCSI bus. If this is + * the case, then it must be reserved. Please set this_id to -1 if + * your setup is in single initiator mode, and the host lacks an + * ID. + */ + int this_id; + + /* + * This determines the degree to which the host adapter is capable + * of scatter-gather. + */ + unsigned short sg_tablesize; + + /* + * Set this if the host adapter has limitations beside segment count. + */ + unsigned short max_sectors; + + /* + * DMA scatter gather segment boundary limit. A segment crossing this + * boundary will be split in two. + */ + unsigned long dma_boundary; + + /* + * This specifies "machine infinity" for host templates which don't + * limit the transfer size. Note this limit represents an absolute + * maximum, and may be over the transfer limits allowed for + * individual devices (e.g. 256 for SCSI-1). + */ +#define SCSI_DEFAULT_MAX_SECTORS 1024 + + /* + * True if this host adapter can make good use of linked commands. + * This will allow more than one command to be queued to a given + * unit on a given host. Set this to the maximum number of command + * blocks to be provided for each device. Set this to 1 for one + * command block per lun, 2 for two, etc. Do not set this to 0. + * You should make sure that the host adapter will do the right thing + * before you try setting this above 1. + */ + short cmd_per_lun; + + /* + * present contains counter indicating how many boards of this + * type were found when we did the scan. + */ + unsigned char present; + + /* + * This specifies the mode that a LLD supports. + */ + unsigned supported_mode:2; + + /* + * True if this host adapter uses unchecked DMA onto an ISA bus. + */ + unsigned unchecked_isa_dma:1; + + /* + * True if this host adapter can make good use of clustering. + * I originally thought that if the tablesize was large that it + * was a waste of CPU cycles to prepare a cluster list, but + * it works out that the Buslogic is faster if you use a smaller + * number of segments (i.e. use clustering). I guess it is + * inefficient. + */ + unsigned use_clustering:1; + + /* + * True for emulated SCSI host adapters (e.g. ATAPI). + */ + unsigned emulated:1; + + /* + * True if the low-level driver performs its own reset-settle delays. + */ + unsigned skip_settle_delay:1; + + /* + * True if we are using ordered write support. + */ + unsigned ordered_tag:1; + + /* + * Countdown for host blocking with no commands outstanding. + */ + unsigned int max_host_blocked; + + /* + * Default value for the blocking. If the queue is empty, + * host_blocked counts down in the request_fn until it restarts + * host operations as zero is reached. + * + * FIXME: This should probably be a value in the template + */ +#define SCSI_DEFAULT_HOST_BLOCKED 7 + + /* + * Pointer to the sysfs class properties for this host, NULL terminated. + */ + struct device_attribute **shost_attrs; + + /* + * Pointer to the SCSI device properties for this host, NULL terminated. + */ + struct device_attribute **sdev_attrs; + + /* + * List of hosts per template. + * + * This is only for use by scsi_module.c for legacy templates. + * For these access to it is synchronized implicitly by + * module_init/module_exit. + */ + struct list_head legacy_hosts; +}; + +/* + * shost state: If you alter this, you also need to alter scsi_sysfs.c + * (for the ascii descriptions) and the state model enforcer: + * scsi_host_set_state() + */ +enum scsi_host_state { + SHOST_CREATED = 1, + SHOST_RUNNING, + SHOST_CANCEL, + SHOST_DEL, + SHOST_RECOVERY, + SHOST_CANCEL_RECOVERY, + SHOST_DEL_RECOVERY, +}; + +struct Scsi_Host { + /* + * __devices is protected by the host_lock, but you should + * usually use scsi_device_lookup / shost_for_each_device + * to access it and don't care about locking yourself. + * In the rare case of beeing in irq context you can use + * their __ prefixed variants with the lock held. NEVER + * access this list directly from a driver. + */ + struct list_head __devices; + struct list_head __targets; + + struct scsi_host_cmd_pool *cmd_pool; + spinlock_t free_list_lock; + struct list_head free_list; /* backup store of cmd structs */ + struct list_head starved_list; + + spinlock_t default_lock; + spinlock_t *host_lock; + + struct mutex scan_mutex;/* serialize scanning activity */ + + struct list_head eh_cmd_q; + struct task_struct * ehandler; /* Error recovery thread. */ + struct completion * eh_action; /* Wait for specific actions on the + host. */ + wait_queue_head_t host_wait; + struct scsi_host_template *hostt; + struct scsi_transport_template *transportt; + + /* + * Area to keep a shared tag map (if needed, will be + * NULL if not). + */ + struct blk_queue_tag *bqt; + + /* + * The following two fields are protected with host_lock; + * however, eh routines can safely access during eh processing + * without acquiring the lock. + */ + unsigned int host_busy; /* commands actually active on low-level */ + unsigned int host_failed; /* commands that failed. */ + unsigned int host_eh_scheduled; /* EH scheduled without command */ + + unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ + int resetting; /* if set, it means that last_reset is a valid value */ + unsigned long last_reset; + + /* + * These three parameters can be used to allow for wide scsi, + * and for host adapters that support multiple busses + * The first two should be set to 1 more than the actual max id + * or lun (i.e. 8 for normal systems). + */ + unsigned int max_id; + unsigned int max_lun; + unsigned int max_channel; + + /* + * This is a unique identifier that must be assigned so that we + * have some way of identifying each detected host adapter properly + * and uniquely. For hosts that do not support more than one card + * in the system at one time, this does not need to be set. It is + * initialized to 0 in scsi_register. + */ + unsigned int unique_id; + + /* + * The maximum length of SCSI commands that this host can accept. + * Probably 12 for most host adapters, but could be 16 for others. + * or 260 if the driver supports variable length cdbs. + * For drivers that don't set this field, a value of 12 is + * assumed. + */ + unsigned short max_cmd_len; + + int this_id; + int can_queue; + short cmd_per_lun; + short unsigned int sg_tablesize; + short unsigned int max_sectors; + unsigned long dma_boundary; + /* + * Used to assign serial numbers to the cmds. + * Protected by the host lock. + */ + unsigned long cmd_serial_number; + + unsigned active_mode:2; + unsigned unchecked_isa_dma:1; + unsigned use_clustering:1; + unsigned use_blk_tcq:1; + + /* + * Host has requested that no further requests come through for the + * time being. + */ + unsigned host_self_blocked:1; + + /* + * Host uses correct SCSI ordering not PC ordering. The bit is + * set for the minority of drivers whose authors actually read + * the spec ;). + */ + unsigned reverse_ordering:1; + + /* + * Ordered write support + */ + unsigned ordered_tag:1; + + /* Task mgmt function in progress */ + unsigned tmf_in_progress:1; + + /* Asynchronous scan in progress */ + unsigned async_scan:1; + + /* + * Optional work queue to be utilized by the transport + */ + char work_q_name[20]; + struct workqueue_struct *work_q; + + /* + * Host has rejected a command because it was busy. + */ + unsigned int host_blocked; + + /* + * Value host_blocked counts down from + */ + unsigned int max_host_blocked; + + /* Protection Information */ + unsigned int prot_capabilities; + unsigned char prot_guard_type; + + /* + * q used for scsi_tgt msgs, async events or any other requests that + * need to be processed in userspace + */ + struct request_queue *uspace_req_q; + + /* legacy crap */ + unsigned long base; + unsigned long io_port; + unsigned char n_io_port; + unsigned char dma_channel; + unsigned int irq; + + + enum scsi_host_state shost_state; + + /* ldm bits */ + struct device shost_gendev, shost_dev; + + /* + * List of hosts per template. + * + * This is only for use by scsi_module.c for legacy templates. + * For these access to it is synchronized implicitly by + * module_init/module_exit. + */ + struct list_head sht_legacy_list; + + /* + * Points to the transport data (if any) which is allocated + * separately + */ + void *shost_data; + + /* + * We should ensure that this is aligned, both for better performance + * and also because some compilers (m68k) don't automatically force + * alignment to a long boundary. + */ + unsigned long hostdata[0] /* Used for storage of host specific stuff */ + __attribute__ ((aligned (sizeof(unsigned long)))); +}; + +#define class_to_shost(d) \ + container_of(d, struct Scsi_Host, shost_dev) + +#define shost_printk(prefix, shost, fmt, a...) \ + dev_printk(prefix, &(shost)->shost_gendev, fmt, ##a) + +static inline void *shost_priv(struct Scsi_Host *shost) +{ + return (void *)shost->hostdata; +} + +int scsi_is_host_device(const struct device *); + +static inline struct Scsi_Host *dev_to_shost(struct device *dev) +{ + while (!scsi_is_host_device(dev)) { + if (!dev->parent) + return NULL; + dev = dev->parent; + } + return container_of(dev, struct Scsi_Host, shost_gendev); +} + +static inline int scsi_host_in_recovery(struct Scsi_Host *shost) +{ + return shost->shost_state == SHOST_RECOVERY || + shost->shost_state == SHOST_CANCEL_RECOVERY || + shost->shost_state == SHOST_DEL_RECOVERY || + shost->tmf_in_progress; +} + +extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); +extern void scsi_flush_work(struct Scsi_Host *); + +extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); +extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *); +extern void scsi_scan_host(struct Scsi_Host *); +extern void scsi_rescan_device(struct device *); +extern void scsi_remove_host(struct Scsi_Host *); +extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); +extern void scsi_host_put(struct Scsi_Host *t); +extern struct Scsi_Host *scsi_host_lookup(unsigned short); +extern const char *scsi_host_state_name(enum scsi_host_state); + +extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); + +static inline struct device *scsi_get_device(struct Scsi_Host *shost) +{ + return shost->shost_gendev.parent; +} + +/** + * scsi_host_scan_allowed - Is scanning of this host allowed + * @shost: Pointer to Scsi_Host. + **/ +static inline int scsi_host_scan_allowed(struct Scsi_Host *shost) +{ + return shost->shost_state == SHOST_RUNNING; +} + +extern void scsi_unblock_requests(struct Scsi_Host *); +extern void scsi_block_requests(struct Scsi_Host *); + +struct class_container; + +extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, + void (*) (struct request_queue *)); +/* + * These two functions are used to allocate and free a pseudo device + * which will connect to the host adapter itself rather than any + * physical device. You must deallocate when you are done with the + * thing. This physical pseudo-device isn't real and won't be available + * from any high-level drivers. + */ +extern void scsi_free_host_dev(struct scsi_device *); +extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); + +/* + * DIF defines the exchange of protection information between + * initiator and SBC block device. + * + * DIX defines the exchange of protection information between OS and + * initiator. + */ +enum scsi_host_prot_capabilities { + SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */ + SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */ + SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */ + + SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */ + SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */ + SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */ + SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */ +}; + +/* + * SCSI hosts which support the Data Integrity Extensions must + * indicate their capabilities by setting the prot_capabilities using + * this call. + */ +static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask) +{ + shost->prot_capabilities = mask; +} + +static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) +{ + return shost->prot_capabilities; +} + +static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) +{ + switch (target_type) { + case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; + case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; + case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; + } + + return 0; +} + +static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) +{ + switch (target_type) { + case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; + case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; + case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; + case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; + } + + return 0; +} + +/* + * All DIX-capable initiators must support the T10-mandated CRC + * checksum. Controllers can optionally implement the IP checksum + * scheme which has much lower impact on system performance. Note + * that the main rationale for the checksum is to match integrity + * metadata with data. Detecting bit errors are a job for ECC memory + * and buses. + */ + +enum scsi_host_guard_type { + SHOST_DIX_GUARD_CRC = 1 << 0, + SHOST_DIX_GUARD_IP = 1 << 1, +}; + +static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type) +{ + shost->prot_guard_type = type; +} + +static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) +{ + return shost->prot_guard_type; +} + +/* legacy interfaces */ +extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); +extern void scsi_unregister(struct Scsi_Host *); +extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state); + +#endif /* _SCSI_SCSI_HOST_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_ioctl.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_ioctl.h.svn-base new file mode 100644 index 00000000..b9006848 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_ioctl.h.svn-base @@ -0,0 +1,48 @@ +#ifndef _SCSI_IOCTL_H +#define _SCSI_IOCTL_H + +#define SCSI_IOCTL_SEND_COMMAND 1 +#define SCSI_IOCTL_TEST_UNIT_READY 2 +#define SCSI_IOCTL_BENCHMARK_COMMAND 3 +#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */ +#define SCSI_IOCTL_START_UNIT 5 +#define SCSI_IOCTL_STOP_UNIT 6 +/* The door lock/unlock constants are compatible with Sun constants for + the cdrom */ +#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */ +#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */ + +#define SCSI_REMOVAL_PREVENT 1 +#define SCSI_REMOVAL_ALLOW 0 + +#ifdef __KERNEL__ + +struct scsi_device; + +/* + * Structures used for scsi_ioctl et al. + */ + +typedef struct scsi_ioctl_command { + unsigned int inlen; + unsigned int outlen; + unsigned char data[0]; +} Scsi_Ioctl_Command; + +typedef struct scsi_idlun { + __u32 dev_id; + __u32 host_unique_id; +} Scsi_Idlun; + +/* Fibre Channel WWN, port_id struct */ +typedef struct scsi_fctargaddress { + __u32 host_port_id; + unsigned char host_wwn[8]; // include NULL term. +} Scsi_FCTargAddress; + +extern int scsi_ioctl(struct scsi_device *, int, void __user *); +extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, + void __user *arg, int ndelay); + +#endif /* __KERNEL__ */ +#endif /* _SCSI_IOCTL_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink.h.svn-base new file mode 100644 index 00000000..536752c4 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink.h.svn-base @@ -0,0 +1,147 @@ +/* + * SCSI Transport Netlink Interface + * Used for the posting of outbound SCSI transport events + * + * Copyright (C) 2006 James Smart, Emulex Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef SCSI_NETLINK_H +#define SCSI_NETLINK_H + +#include <linux/netlink.h> + + +/* + * This file intended to be included by both kernel and user space + */ + +/* Single Netlink Message type to send all SCSI Transport messages */ +#define SCSI_TRANSPORT_MSG NLMSG_MIN_TYPE + 1 + +/* SCSI Transport Broadcast Groups */ + /* leaving groups 0 and 1 unassigned */ +#define SCSI_NL_GRP_FC_EVENTS (1<<2) /* Group 2 */ +#define SCSI_NL_GRP_CNT 3 + + +/* SCSI_TRANSPORT_MSG event message header */ +struct scsi_nl_hdr { + uint8_t version; + uint8_t transport; + uint16_t magic; + uint16_t msgtype; + uint16_t msglen; +} __attribute__((aligned(sizeof(uint64_t)))); + +/* scsi_nl_hdr->version value */ +#define SCSI_NL_VERSION 1 + +/* scsi_nl_hdr->magic value */ +#define SCSI_NL_MAGIC 0xA1B2 + +/* scsi_nl_hdr->transport value */ +#define SCSI_NL_TRANSPORT 0 +#define SCSI_NL_TRANSPORT_FC 1 +#define SCSI_NL_MAX_TRANSPORTS 2 + +/* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */ + +/* + * GENERIC SCSI scsi_nl_hdr->msgtype Values + */ + /* kernel -> user */ +#define SCSI_NL_SHOST_VENDOR 0x0001 + /* user -> kernel */ +/* SCSI_NL_SHOST_VENDOR msgtype is kernel->user and user->kernel */ + + +/* + * Message Structures : + */ + +/* macro to round up message lengths to 8byte boundary */ +#define SCSI_NL_MSGALIGN(len) (((len) + 7) & ~7) + + +/* + * SCSI HOST Vendor Unique messages : + * SCSI_NL_SHOST_VENDOR + * + * Note: The Vendor Unique message payload will begin directly after + * this structure, with the length of the payload per vmsg_datalen. + * + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID + * formatting requirements specified below + */ +struct scsi_nl_host_vendor_msg { + struct scsi_nl_hdr snlh; /* must be 1st element ! */ + uint64_t vendor_id; + uint16_t host_no; + uint16_t vmsg_datalen; +} __attribute__((aligned(sizeof(uint64_t)))); + + +/* + * Vendor ID: + * If transports post vendor-unique events, they must pass a well-known + * 32-bit vendor identifier. This identifier consists of 8 bits indicating + * the "type" of identifier contained, and 24 bits of id data. + * + * Identifiers for each type: + * PCI : ID data is the 16 bit PCI Registered Vendor ID + */ +#define SCSI_NL_VID_TYPE_SHIFT 56 +#define SCSI_NL_VID_TYPE_MASK ((u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_TYPE_PCI ((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_ID_MASK (~ SCSI_NL_VID_TYPE_MASK) + + +#define INIT_SCSI_NL_HDR(hdr, t, mtype, mlen) \ + { \ + (hdr)->version = SCSI_NL_VERSION; \ + (hdr)->transport = t; \ + (hdr)->magic = SCSI_NL_MAGIC; \ + (hdr)->msgtype = mtype; \ + (hdr)->msglen = mlen; \ + } + + +#ifdef __KERNEL__ + +#include <scsi/scsi_host.h> + +/* Exported Kernel Interfaces */ +int scsi_nl_add_transport(u8 tport, + int (*msg_handler)(struct sk_buff *), + void (*event_handler)(struct notifier_block *, unsigned long, void *)); +void scsi_nl_remove_transport(u8 tport); + +int scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt, + int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload, + u32 len, u32 pid), + void (*nlevt_handler)(struct notifier_block *nb, + unsigned long event, void *notify_ptr)); +void scsi_nl_remove_driver(u64 vendor_id); + +void scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr); +int scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id, + char *data_buf, u32 data_len); + +#endif /* __KERNEL__ */ + +#endif /* SCSI_NETLINK_H */ + diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink_fc.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink_fc.h.svn-base new file mode 100644 index 00000000..cbf76e47 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_netlink_fc.h.svn-base @@ -0,0 +1,71 @@ +/* + * FC Transport Netlink Interface + * + * Copyright (C) 2006 James Smart, Emulex Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef SCSI_NETLINK_FC_H +#define SCSI_NETLINK_FC_H + +#include <scsi/scsi_netlink.h> + +/* + * This file intended to be included by both kernel and user space + */ + +/* + * FC Transport Message Types + */ + /* kernel -> user */ +#define FC_NL_ASYNC_EVENT 0x0100 + /* user -> kernel */ +/* none */ + + +/* + * Message Structures : + */ + +/* macro to round up message lengths to 8byte boundary */ +#define FC_NL_MSGALIGN(len) (((len) + 7) & ~7) + + +/* + * FC Transport Broadcast Event Message : + * FC_NL_ASYNC_EVENT + * + * Note: if Vendor Unique message, &event_data will be start of + * vendor unique payload, and the length of the payload is + * per event_datalen + * + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID + * formatting requirements specified in scsi_netlink.h + */ +struct fc_nl_event { + struct scsi_nl_hdr snlh; /* must be 1st element ! */ + uint64_t seconds; + uint64_t vendor_id; + uint16_t host_no; + uint16_t event_datalen; + uint32_t event_num; + uint32_t event_code; + uint32_t event_data; +} __attribute__((aligned(sizeof(uint64_t)))); + + +#endif /* SCSI_NETLINK_FC_H */ + diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tcq.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tcq.h.svn-base new file mode 100644 index 00000000..17231385 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tcq.h.svn-base @@ -0,0 +1,178 @@ +#ifndef _SCSI_SCSI_TCQ_H +#define _SCSI_SCSI_TCQ_H + +#include <linux/blkdev.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_host.h> + +#define MSG_SIMPLE_TAG 0x20 +#define MSG_HEAD_TAG 0x21 +#define MSG_ORDERED_TAG 0x22 + +#define SCSI_NO_TAG (-1) /* identify no tag in use */ + + +#ifdef CONFIG_BLOCK + +/** + * scsi_get_tag_type - get the type of tag the device supports + * @sdev: the scsi device + * + * Notes: + * If the drive only supports simple tags, returns MSG_SIMPLE_TAG + * if it supports all tag types, returns MSG_ORDERED_TAG. + */ +static inline int scsi_get_tag_type(struct scsi_device *sdev) +{ + if (!sdev->tagged_supported) + return 0; + if (sdev->ordered_tags) + return MSG_ORDERED_TAG; + if (sdev->simple_tags) + return MSG_SIMPLE_TAG; + return 0; +} + +static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) +{ + switch (tag) { + case MSG_ORDERED_TAG: + sdev->ordered_tags = 1; + /* fall through */ + case MSG_SIMPLE_TAG: + sdev->simple_tags = 1; + break; + case 0: + /* fall through */ + default: + sdev->ordered_tags = 0; + sdev->simple_tags = 0; + break; + } +} +/** + * scsi_activate_tcq - turn on tag command queueing + * @SDpnt: device to turn on TCQ for + * @depth: queue depth + * + * Notes: + * Eventually, I hope depth would be the maximum depth + * the device could cope with and the real queue depth + * would be adjustable from 0 to depth. + **/ +static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) +{ + if (!sdev->tagged_supported) + return; + + if (!blk_queue_tagged(sdev->request_queue)) + blk_queue_init_tags(sdev->request_queue, depth, + sdev->host->bqt); + + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); +} + +/** + * scsi_deactivate_tcq - turn off tag command queueing + * @SDpnt: device to turn off TCQ for + **/ +static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) +{ + if (blk_queue_tagged(sdev->request_queue)) + blk_queue_free_tags(sdev->request_queue); + scsi_adjust_queue_depth(sdev, 0, depth); +} + +/** + * scsi_populate_tag_msg - place a tag message in a buffer + * @SCpnt: pointer to the Scsi_Cmnd for the tag + * @msg: pointer to the area to place the tag + * + * Notes: + * designed to create the correct type of tag message for the + * particular request. Returns the size of the tag message. + * May return 0 if TCQ is disabled for this device. + **/ +static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) +{ + struct request *req = cmd->request; + struct scsi_device *sdev = cmd->device; + + if (blk_rq_tagged(req)) { + if (sdev->ordered_tags && req->cmd_flags & REQ_HARDBARRIER) + *msg++ = MSG_ORDERED_TAG; + else + *msg++ = MSG_SIMPLE_TAG; + *msg++ = req->tag; + return 2; + } + + return 0; +} + +/** + * scsi_find_tag - find a tagged command by device + * @SDpnt: pointer to the ScSI device + * @tag: the tag number + * + * Notes: + * Only works with tags allocated by the generic blk layer. + **/ +static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) +{ + + struct request *req; + + if (tag != SCSI_NO_TAG) { + req = blk_queue_find_tag(sdev->request_queue, tag); + return req ? (struct scsi_cmnd *)req->special : NULL; + } + + /* single command, look in space */ + return sdev->current_cmnd; +} + +/** + * scsi_init_shared_tag_map - create a shared tag map + * @shost: the host to share the tag map among all devices + * @depth: the total depth of the map + */ +static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) +{ + /* + * If the shared tag map isn't already initialized, do it now. + * This saves callers from having to check ->bqt when setting up + * devices on the shared host (for libata) + */ + if (!shost->bqt) { + shost->bqt = blk_init_tags(depth); + if (!shost->bqt) + return -ENOMEM; + } + + return 0; +} + +/** + * scsi_host_find_tag - find the tagged command by host + * @shost: pointer to scsi_host + * @tag: tag of the scsi_cmnd + * + * Notes: + * Only works with tags allocated by the generic blk layer. + **/ +static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, + int tag) +{ + struct request *req; + + if (tag != SCSI_NO_TAG) { + req = blk_map_queue_find_tag(shost->bqt, tag); + return req ? (struct scsi_cmnd *)req->special : NULL; + } + return NULL; +} + +#endif /* CONFIG_BLOCK */ +#endif /* _SCSI_SCSI_TCQ_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt.h.svn-base new file mode 100644 index 00000000..d0fefb96 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt.h.svn-base @@ -0,0 +1,21 @@ +/* + * SCSI target definitions + */ + +#include <linux/dma-mapping.h> + +struct Scsi_Host; +struct scsi_cmnd; +struct scsi_lun; + +extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *); +extern int scsi_tgt_alloc_queue(struct Scsi_Host *); +extern void scsi_tgt_free_queue(struct Scsi_Host *); +extern int scsi_tgt_queue_command(struct scsi_cmnd *, u64, struct scsi_lun *, u64); +extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, u64, int, u64, + struct scsi_lun *, void *); +extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *, + enum dma_data_direction, gfp_t); +extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *); +extern int scsi_tgt_it_nexus_create(struct Scsi_Host *, u64, char *); +extern int scsi_tgt_it_nexus_destroy(struct Scsi_Host *, u64); diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt_if.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt_if.h.svn-base new file mode 100644 index 00000000..f2ee7c23 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_tgt_if.h.svn-base @@ -0,0 +1,108 @@ +/* + * SCSI target kernel/user interface + * + * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> + * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef __SCSI_TARGET_IF_H +#define __SCSI_TARGET_IF_H + +/* user -> kernel */ +#define TGT_UEVENT_CMD_RSP 0x0001 +#define TGT_UEVENT_IT_NEXUS_RSP 0x0002 +#define TGT_UEVENT_TSK_MGMT_RSP 0x0003 + +/* kernel -> user */ +#define TGT_KEVENT_CMD_REQ 0x1001 +#define TGT_KEVENT_CMD_DONE 0x1002 +#define TGT_KEVENT_IT_NEXUS_REQ 0x1003 +#define TGT_KEVENT_TSK_MGMT_REQ 0x1004 + +struct tgt_event_hdr { + uint16_t version; + uint16_t status; + uint16_t type; + uint16_t len; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +struct tgt_event { + struct tgt_event_hdr hdr; + + union { + /* user-> kernel */ + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 tag; + aligned_u64 uaddr; + aligned_u64 sense_uaddr; + uint32_t len; + uint32_t sense_len; + uint8_t rw; + } cmd_rsp; + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 mid; + } tsk_mgmt_rsp; + struct { + __s32 host_no; + __s32 result; + aligned_u64 itn_id; + __u32 function; + } it_nexus_rsp; + + /* kernel -> user */ + struct { + int host_no; + uint32_t data_len; + aligned_u64 itn_id; + uint8_t scb[16]; + uint8_t lun[8]; + int attribute; + aligned_u64 tag; + } cmd_req; + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 tag; + } cmd_done; + struct { + int host_no; + int function; + aligned_u64 itn_id; + aligned_u64 tag; + uint8_t lun[8]; + aligned_u64 mid; + } tsk_mgmt_req; + struct { + __s32 host_no; + __u32 function; + aligned_u64 itn_id; + __u32 max_cmds; + __u8 initiator_id[16]; + } it_nexus_req; + } p; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +#define TGT_RING_SIZE (1UL << 16) + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport.h.svn-base new file mode 100644 index 00000000..0de32cd4 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport.h.svn-base @@ -0,0 +1,121 @@ +/* + * Transport specific attributes. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef SCSI_TRANSPORT_H +#define SCSI_TRANSPORT_H + +#include <linux/transport_class.h> +#include <linux/blkdev.h> +#include <scsi/scsi_host.h> +#include <scsi/scsi_device.h> + +struct scsi_transport_template { + /* the attribute containers */ + struct transport_container host_attrs; + struct transport_container target_attrs; + struct transport_container device_attrs; + + /* + * If set, called from sysfs and legacy procfs rescanning code. + */ + int (*user_scan)(struct Scsi_Host *, uint, uint, uint); + + /* The size of the specific transport attribute structure (a + * space of this size will be left at the end of the + * scsi_* structure */ + int device_size; + int device_private_offset; + int target_size; + int target_private_offset; + int host_size; + /* no private offset for the host; there's an alternative mechanism */ + + /* + * True if the transport wants to use a host-based work-queue + */ + unsigned int create_work_queue : 1; + + /* + * Allows a transport to override the default error handler. + */ + void (* eh_strategy_handler)(struct Scsi_Host *); + + /* + * This is an optional routine that allows the transport to become + * involved when a scsi io timer fires. The return value tells the + * timer routine how to finish the io timeout handling: + * EH_HANDLED: I fixed the error, please complete the command + * EH_RESET_TIMER: I need more time, reset the timer and + * begin counting again + * EH_NOT_HANDLED Begin normal error recovery + */ + enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); + + /* + * Used as callback for the completion of i_t_nexus request + * for target drivers. + */ + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + + /* + * Used as callback for the completion of task management + * request for target drivers. + */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); +}; + +#define transport_class_to_shost(tc) \ + dev_to_shost((tc)->parent) + + +/* Private area maintenance. The driver requested allocations come + * directly after the transport class allocations (if any). The idea + * is that you *must* call these only once. The code assumes that the + * initial values are the ones the transport specific code requires */ +static inline void +scsi_transport_reserve_target(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->target_private_offset != 0); + t->target_private_offset = ALIGN(t->target_size, sizeof(void *)); + t->target_size = t->target_private_offset + space; +} +static inline void +scsi_transport_reserve_device(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->device_private_offset != 0); + t->device_private_offset = ALIGN(t->device_size, sizeof(void *)); + t->device_size = t->device_private_offset + space; +} +static inline void * +scsi_transport_target_data(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(&starget->dev); + return (u8 *)starget->starget_data + + shost->transportt->target_private_offset; + +} +static inline void * +scsi_transport_device_data(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + return (u8 *)sdev->sdev_data + + shost->transportt->device_private_offset; +} + +#endif /* SCSI_TRANSPORT_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_fc.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_fc.h.svn-base new file mode 100644 index 00000000..c9184f75 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_fc.h.svn-base @@ -0,0 +1,763 @@ +/* + * FiberChannel transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ======== + * + * Copyright (C) 2004-2007 James Smart, Emulex Corporation + * Rewrite for host, target, device, and remote port attributes, + * statistics, and service functions... + * + */ +#ifndef SCSI_TRANSPORT_FC_H +#define SCSI_TRANSPORT_FC_H + +#include <linux/sched.h> +#include <scsi/scsi.h> +#include <scsi/scsi_netlink.h> + +struct scsi_transport_template; + + +/* + * FC Port definitions - Following FC HBAAPI guidelines + * + * Note: Not all binary values for the different fields match HBAAPI. + * Instead, we use densely packed ordinal values or enums. + * We get away with this as we never present the actual binary values + * externally. For sysfs, we always present the string that describes + * the value. Thus, an admin doesn't need a magic HBAAPI decoder ring + * to understand the values. The HBAAPI user-space library is free to + * convert the strings into the HBAAPI-specified binary values. + * + * Note: Not all HBAAPI-defined values are contained in the definitions + * below. Those not appropriate to an fc_host (e.g. FCP initiator) have + * been removed. + */ + +/* + * fc_port_type: If you alter this, you also need to alter scsi_transport_fc.c + * (for the ascii descriptions). + */ +enum fc_port_type { + FC_PORTTYPE_UNKNOWN, + FC_PORTTYPE_OTHER, + FC_PORTTYPE_NOTPRESENT, + FC_PORTTYPE_NPORT, /* Attached to FPort */ + FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */ + FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */ + FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */ + FC_PORTTYPE_NPIV, /* VPORT based on NPIV */ +}; + + +/* + * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c + * (for the ascii descriptions). + */ +enum fc_port_state { + FC_PORTSTATE_UNKNOWN, + FC_PORTSTATE_NOTPRESENT, + FC_PORTSTATE_ONLINE, + FC_PORTSTATE_OFFLINE, /* User has taken Port Offline */ + FC_PORTSTATE_BLOCKED, + FC_PORTSTATE_BYPASSED, + FC_PORTSTATE_DIAGNOSTICS, + FC_PORTSTATE_LINKDOWN, + FC_PORTSTATE_ERROR, + FC_PORTSTATE_LOOPBACK, + FC_PORTSTATE_DELETED, +}; + + +/* + * fc_vport_state: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_vport_state { + FC_VPORT_UNKNOWN, + FC_VPORT_ACTIVE, + FC_VPORT_DISABLED, + FC_VPORT_LINKDOWN, + FC_VPORT_INITIALIZING, + FC_VPORT_NO_FABRIC_SUPP, + FC_VPORT_NO_FABRIC_RSCS, + FC_VPORT_FABRIC_LOGOUT, + FC_VPORT_FABRIC_REJ_WWN, + FC_VPORT_FAILED, +}; + + + +/* + * FC Classes of Service + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report supported_classes). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_COS_UNSPECIFIED 0 +#define FC_COS_CLASS1 2 +#define FC_COS_CLASS2 4 +#define FC_COS_CLASS3 8 +#define FC_COS_CLASS4 0x10 +#define FC_COS_CLASS6 0x40 + +/* + * FC Port Speeds + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report supported_speeds). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver + incapable of reporting */ +#define FC_PORTSPEED_1GBIT 1 +#define FC_PORTSPEED_2GBIT 2 +#define FC_PORTSPEED_4GBIT 4 +#define FC_PORTSPEED_10GBIT 8 +#define FC_PORTSPEED_8GBIT 0x10 +#define FC_PORTSPEED_16GBIT 0x20 +#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ + +/* + * fc_tgtid_binding_type: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_tgtid_binding_type { + FC_TGTID_BIND_NONE, + FC_TGTID_BIND_BY_WWPN, + FC_TGTID_BIND_BY_WWNN, + FC_TGTID_BIND_BY_ID, +}; + +/* + * FC Port Roles + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report roles). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_PORT_ROLE_UNKNOWN 0x00 +#define FC_PORT_ROLE_FCP_TARGET 0x01 +#define FC_PORT_ROLE_FCP_INITIATOR 0x02 +#define FC_PORT_ROLE_IP_PORT 0x04 + +/* The following are for compatibility */ +#define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN +#define FC_RPORT_ROLE_FCP_TARGET FC_PORT_ROLE_FCP_TARGET +#define FC_RPORT_ROLE_FCP_INITIATOR FC_PORT_ROLE_FCP_INITIATOR +#define FC_RPORT_ROLE_IP_PORT FC_PORT_ROLE_IP_PORT + + +/* Macro for use in defining Virtual Port attributes */ +#define FC_VPORT_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_vport_##_name = \ + __ATTR(_name,_mode,_show,_store) + +/* + * fc_vport_identifiers: This set of data contains all elements + * to uniquely identify and instantiate a FC virtual port. + * + * Notes: + * symbolic_name: The driver is to append the symbolic_name string data + * to the symbolic_node_name data that it generates by default. + * the resulting combination should then be registered with the switch. + * It is expected that things like Xen may stuff a VM title into + * this field. + */ +#define FC_VPORT_SYMBOLIC_NAMELEN 64 +struct fc_vport_identifiers { + u64 node_name; + u64 port_name; + u32 roles; + bool disable; + enum fc_port_type vport_type; /* only FC_PORTTYPE_NPIV allowed */ + char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; +}; + +/* + * FC Virtual Port Attributes + * + * This structure exists for each FC port is a virtual FC port. Virtual + * ports share the physical link with the Physical port. Each virtual + * ports has a unique presense on the SAN, and may be instantiated via + * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a + * unique presense, each vport has it's own view of the fabric, + * authentication privilege, and priorities. + * + * A virtual port may support 1 or more FC4 roles. Typically it is a + * FCP Initiator. It could be a FCP Target, or exist sole for an IP over FC + * roles. FC port attributes for the vport will be reported on any + * fc_host class object allocated for an FCP Initiator. + * + * -- + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after receiving the fc_vport structure + * via the vport_create() call from the transport. + * The transport fully manages all get functions w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +struct fc_vport { + /* Fixed Attributes */ + + /* Dynamic Attributes */ + + /* Private (Transport-managed) Attributes */ + enum fc_vport_state vport_state; + enum fc_vport_state vport_last_state; + u64 node_name; + u64 port_name; + u32 roles; + u32 vport_id; /* Admin Identifier for the vport */ + enum fc_port_type vport_type; + char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; + + /* exported data */ + void *dd_data; /* Used for driver-specific storage */ + + /* internal data */ + struct Scsi_Host *shost; /* Physical Port Parent */ + unsigned int channel; + u32 number; + u8 flags; + struct list_head peers; + struct device dev; + struct work_struct vport_delete_work; +} __attribute__((aligned(sizeof(unsigned long)))); + +/* bit field values for struct fc_vport "flags" field: */ +#define FC_VPORT_CREATING 0x01 +#define FC_VPORT_DELETING 0x02 +#define FC_VPORT_DELETED 0x04 +#define FC_VPORT_DEL 0x06 /* Any DELETE state */ + +#define dev_to_vport(d) \ + container_of(d, struct fc_vport, dev) +#define transport_class_to_vport(dev) \ + dev_to_vport(dev->parent) +#define vport_to_shost(v) \ + (v->shost) +#define vport_to_shost_channel(v) \ + (v->channel) +#define vport_to_parent(v) \ + (v->dev.parent) + + +/* Error return codes for vport_create() callback */ +#define VPCERR_UNSUPPORTED -ENOSYS /* no driver/adapter + support */ +#define VPCERR_BAD_WWN -ENOTUNIQ /* driver validation + of WWNs failed */ +#define VPCERR_NO_FABRIC_SUPP -EOPNOTSUPP /* Fabric connection + is loop or the + Fabric Port does + not support NPIV */ + +/* + * fc_rport_identifiers: This set of data contains all elements + * to uniquely identify a remote FC port. The driver uses this data + * to report the existence of a remote FC port in the topology. Internally, + * the transport uses this data for attributes and to manage consistent + * target id bindings. + */ +struct fc_rport_identifiers { + u64 node_name; + u64 port_name; + u32 port_id; + u32 roles; +}; + + +/* Macro for use in defining Remote Port attributes */ +#define FC_RPORT_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_rport_##_name = \ + __ATTR(_name,_mode,_show,_store) + + +/* + * FC Remote Port Attributes + * + * This structure exists for each remote FC port that a LLDD notifies + * the subsystem of. A remote FC port may or may not be a SCSI Target, + * also be a SCSI initiator, IP endpoint, etc. As such, the remote + * port is considered a separate entity, independent of "role" (such + * as scsi target). + * + * -- + * + * Attributes are based on HBAAPI V2.0 definitions. Only those + * attributes that are determinable by the local port (aka Host) + * are contained. + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after successfully calling + * fc_remote_port_add(). The transport fully manages all get functions + * w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +struct fc_rport { /* aka fc_starget_attrs */ + /* Fixed Attributes */ + u32 maxframe_size; + u32 supported_classes; + + /* Dynamic Attributes */ + u32 dev_loss_tmo; /* Remote Port loss timeout in seconds. */ + + /* Private (Transport-managed) Attributes */ + u64 node_name; + u64 port_name; + u32 port_id; + u32 roles; + enum fc_port_state port_state; /* Will only be ONLINE or UNKNOWN */ + u32 scsi_target_id; + u32 fast_io_fail_tmo; + + /* exported data */ + void *dd_data; /* Used for driver-specific storage */ + + /* internal data */ + unsigned int channel; + u32 number; + u8 flags; + struct list_head peers; + struct device dev; + struct delayed_work dev_loss_work; + struct work_struct scan_work; + struct delayed_work fail_io_work; + struct work_struct stgt_delete_work; + struct work_struct rport_delete_work; +} __attribute__((aligned(sizeof(unsigned long)))); + +/* bit field values for struct fc_rport "flags" field: */ +#define FC_RPORT_DEVLOSS_PENDING 0x01 +#define FC_RPORT_SCAN_PENDING 0x02 +#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x04 +#define FC_RPORT_DEVLOSS_CALLBK_DONE 0x08 + +#define dev_to_rport(d) \ + container_of(d, struct fc_rport, dev) +#define transport_class_to_rport(dev) \ + dev_to_rport(dev->parent) +#define rport_to_shost(r) \ + dev_to_shost(r->dev.parent) + +/* + * FC SCSI Target Attributes + * + * The SCSI Target is considered an extention of a remote port (as + * a remote port can be more than a SCSI Target). Within the scsi + * subsystem, we leave the Target as a separate entity. Doing so + * provides backward compatibility with prior FC transport api's, + * and lets remote ports be handled entirely within the FC transport + * and independently from the scsi subsystem. The drawback is that + * some data will be duplicated. + */ + +struct fc_starget_attrs { /* aka fc_target_attrs */ + /* Dynamic Attributes */ + u64 node_name; + u64 port_name; + u32 port_id; +}; + +#define fc_starget_node_name(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->node_name) +#define fc_starget_port_name(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->port_name) +#define fc_starget_port_id(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->port_id) + +#define starget_to_rport(s) \ + scsi_is_fc_rport(s->dev.parent) ? dev_to_rport(s->dev.parent) : NULL + + +/* + * FC Local Port (Host) Statistics + */ + +/* FC Statistics - Following FC HBAAPI v2.0 guidelines */ +struct fc_host_statistics { + /* port statistics */ + u64 seconds_since_last_reset; + u64 tx_frames; + u64 tx_words; + u64 rx_frames; + u64 rx_words; + u64 lip_count; + u64 nos_count; + u64 error_frames; + u64 dumped_frames; + u64 link_failure_count; + u64 loss_of_sync_count; + u64 loss_of_signal_count; + u64 prim_seq_protocol_err_count; + u64 invalid_tx_word_count; + u64 invalid_crc_count; + + /* fc4 statistics (only FCP supported currently) */ + u64 fcp_input_requests; + u64 fcp_output_requests; + u64 fcp_control_requests; + u64 fcp_input_megabytes; + u64 fcp_output_megabytes; +}; + + +/* + * FC Event Codes - Polled and Async, following FC HBAAPI v2.0 guidelines + */ + +/* + * fc_host_event_code: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_host_event_code { + FCH_EVT_LIP = 0x1, + FCH_EVT_LINKUP = 0x2, + FCH_EVT_LINKDOWN = 0x3, + FCH_EVT_LIPRESET = 0x4, + FCH_EVT_RSCN = 0x5, + FCH_EVT_ADAPTER_CHANGE = 0x103, + FCH_EVT_PORT_UNKNOWN = 0x200, + FCH_EVT_PORT_OFFLINE = 0x201, + FCH_EVT_PORT_ONLINE = 0x202, + FCH_EVT_PORT_FABRIC = 0x204, + FCH_EVT_LINK_UNKNOWN = 0x500, + FCH_EVT_VENDOR_UNIQUE = 0xffff, +}; + + +/* + * FC Local Port (Host) Attributes + * + * Attributes are based on HBAAPI V2.0 definitions. + * Note: OSDeviceName is determined by user-space library + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after successfully calling scsi_add_host(). + * The transport fully manages all get functions w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +#define FC_FC4_LIST_SIZE 32 +#define FC_SYMBOLIC_NAME_SIZE 256 +#define FC_VERSION_STRING_SIZE 64 +#define FC_SERIAL_NUMBER_SIZE 80 + +struct fc_host_attrs { + /* Fixed Attributes */ + u64 node_name; + u64 port_name; + u64 permanent_port_name; + u32 supported_classes; + u8 supported_fc4s[FC_FC4_LIST_SIZE]; + u32 supported_speeds; + u32 maxframe_size; + u16 max_npiv_vports; + char serial_number[FC_SERIAL_NUMBER_SIZE]; + + /* Dynamic Attributes */ + u32 port_id; + enum fc_port_type port_type; + enum fc_port_state port_state; + u8 active_fc4s[FC_FC4_LIST_SIZE]; + u32 speed; + u64 fabric_name; + char symbolic_name[FC_SYMBOLIC_NAME_SIZE]; + char system_hostname[FC_SYMBOLIC_NAME_SIZE]; + + /* Private (Transport-managed) Attributes */ + enum fc_tgtid_binding_type tgtid_bind_type; + + /* internal data */ + struct list_head rports; + struct list_head rport_bindings; + struct list_head vports; + u32 next_rport_number; + u32 next_target_id; + u32 next_vport_number; + u16 npiv_vports_inuse; + + /* work queues for rport state manipulation */ + char work_q_name[20]; + struct workqueue_struct *work_q; + char devloss_work_q_name[20]; + struct workqueue_struct *devloss_work_q; +}; + +#define shost_to_fc_host(x) \ + ((struct fc_host_attrs *)(x)->shost_data) + +#define fc_host_node_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->node_name) +#define fc_host_port_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_name) +#define fc_host_permanent_port_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->permanent_port_name) +#define fc_host_supported_classes(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_classes) +#define fc_host_supported_fc4s(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_fc4s) +#define fc_host_supported_speeds(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds) +#define fc_host_maxframe_size(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size) +#define fc_host_max_npiv_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports) +#define fc_host_serial_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->serial_number) +#define fc_host_port_id(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_id) +#define fc_host_port_type(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_type) +#define fc_host_port_state(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_state) +#define fc_host_active_fc4s(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->active_fc4s) +#define fc_host_speed(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->speed) +#define fc_host_fabric_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->fabric_name) +#define fc_host_symbolic_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->symbolic_name) +#define fc_host_system_hostname(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->system_hostname) +#define fc_host_tgtid_bind_type(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->tgtid_bind_type) +#define fc_host_rports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->rports) +#define fc_host_rport_bindings(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings) +#define fc_host_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->vports) +#define fc_host_next_rport_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) +#define fc_host_next_target_id(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) +#define fc_host_next_vport_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_vport_number) +#define fc_host_npiv_vports_inuse(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse) +#define fc_host_work_q_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->work_q_name) +#define fc_host_work_q(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->work_q) +#define fc_host_devloss_work_q_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q_name) +#define fc_host_devloss_work_q(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q) + + +/* The functions by which the transport class and the driver communicate */ +struct fc_function_template { + void (*get_rport_dev_loss_tmo)(struct fc_rport *); + void (*set_rport_dev_loss_tmo)(struct fc_rport *, u32); + + void (*get_starget_node_name)(struct scsi_target *); + void (*get_starget_port_name)(struct scsi_target *); + void (*get_starget_port_id)(struct scsi_target *); + + void (*get_host_port_id)(struct Scsi_Host *); + void (*get_host_port_type)(struct Scsi_Host *); + void (*get_host_port_state)(struct Scsi_Host *); + void (*get_host_active_fc4s)(struct Scsi_Host *); + void (*get_host_speed)(struct Scsi_Host *); + void (*get_host_fabric_name)(struct Scsi_Host *); + void (*get_host_symbolic_name)(struct Scsi_Host *); + void (*set_host_system_hostname)(struct Scsi_Host *); + + struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *); + void (*reset_fc_host_stats)(struct Scsi_Host *); + + int (*issue_fc_host_lip)(struct Scsi_Host *); + + void (*dev_loss_tmo_callbk)(struct fc_rport *); + void (*terminate_rport_io)(struct fc_rport *); + + void (*set_vport_symbolic_name)(struct fc_vport *); + int (*vport_create)(struct fc_vport *, bool); + int (*vport_disable)(struct fc_vport *, bool); + int (*vport_delete)(struct fc_vport *); + + /* target-mode drivers' functions */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + + /* allocation lengths for host-specific data */ + u32 dd_fcrport_size; + u32 dd_fcvport_size; + + /* + * The driver sets these to tell the transport class it + * wants the attributes displayed in sysfs. If the show_ flag + * is not set, the attribute will be private to the transport + * class + */ + + /* remote port fixed attributes */ + unsigned long show_rport_maxframe_size:1; + unsigned long show_rport_supported_classes:1; + unsigned long show_rport_dev_loss_tmo:1; + + /* + * target dynamic attributes + * These should all be "1" if the driver uses the remote port + * add/delete functions (so attributes reflect rport values). + */ + unsigned long show_starget_node_name:1; + unsigned long show_starget_port_name:1; + unsigned long show_starget_port_id:1; + + /* host fixed attributes */ + unsigned long show_host_node_name:1; + unsigned long show_host_port_name:1; + unsigned long show_host_permanent_port_name:1; + unsigned long show_host_supported_classes:1; + unsigned long show_host_supported_fc4s:1; + unsigned long show_host_supported_speeds:1; + unsigned long show_host_maxframe_size:1; + unsigned long show_host_serial_number:1; + /* host dynamic attributes */ + unsigned long show_host_port_id:1; + unsigned long show_host_port_type:1; + unsigned long show_host_port_state:1; + unsigned long show_host_active_fc4s:1; + unsigned long show_host_speed:1; + unsigned long show_host_fabric_name:1; + unsigned long show_host_symbolic_name:1; + unsigned long show_host_system_hostname:1; + + unsigned long disable_target_scan:1; +}; + + +/** + * fc_remote_port_chkready - called to validate the remote port state + * prior to initiating io to the port. + * + * Returns a scsi result code that can be returned by the LLDD. + * + * @rport: remote port to be checked + **/ +static inline int +fc_remote_port_chkready(struct fc_rport *rport) +{ + int result; + + switch (rport->port_state) { + case FC_PORTSTATE_ONLINE: + if (rport->roles & FC_PORT_ROLE_FCP_TARGET) + result = 0; + else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) + result = DID_TRANSPORT_DISRUPTED << 16; + else + result = DID_NO_CONNECT << 16; + break; + case FC_PORTSTATE_BLOCKED: + if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) + result = DID_TRANSPORT_FAILFAST << 16; + else + result = DID_TRANSPORT_DISRUPTED << 16; + break; + default: + result = DID_NO_CONNECT << 16; + break; + } + return result; +} + +static inline u64 wwn_to_u64(u8 *wwn) +{ + return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 | + (u64)wwn[2] << 40 | (u64)wwn[3] << 32 | + (u64)wwn[4] << 24 | (u64)wwn[5] << 16 | + (u64)wwn[6] << 8 | (u64)wwn[7]; +} + +static inline void u64_to_wwn(u64 inm, u8 *wwn) +{ + wwn[0] = (inm >> 56) & 0xff; + wwn[1] = (inm >> 48) & 0xff; + wwn[2] = (inm >> 40) & 0xff; + wwn[3] = (inm >> 32) & 0xff; + wwn[4] = (inm >> 24) & 0xff; + wwn[5] = (inm >> 16) & 0xff; + wwn[6] = (inm >> 8) & 0xff; + wwn[7] = inm & 0xff; +} + +/** + * fc_vport_set_state() - called to set a vport's state. Saves the old state, + * excepting the transitory states of initializing and sending the ELS + * traffic to instantiate the vport on the link. + * + * Assumes the driver has surrounded this with the proper locking to ensure + * a coherent state change. + * + * @vport: virtual port whose state is changing + * @new_state: new state + **/ +static inline void +fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state) +{ + if ((new_state != FC_VPORT_UNKNOWN) && + (new_state != FC_VPORT_INITIALIZING)) + vport->vport_last_state = vport->vport_state; + vport->vport_state = new_state; +} + + +struct scsi_transport_template *fc_attach_transport( + struct fc_function_template *); +void fc_release_transport(struct scsi_transport_template *); +void fc_remove_host(struct Scsi_Host *); +struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, + int channel, struct fc_rport_identifiers *ids); +void fc_remote_port_delete(struct fc_rport *rport); +void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles); +int scsi_is_fc_rport(const struct device *); +u32 fc_get_event_number(void); +void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, + enum fc_host_event_code event_code, u32 event_data); +void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, + u32 data_len, char * data_buf, u64 vendor_id); + /* Note: when specifying vendor_id to fc_host_post_vendor_event() + * be sure to read the Vendor Type and ID formatting requirements + * specified in scsi_netlink.h + */ +struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, + struct fc_vport_identifiers *); +int fc_vport_terminate(struct fc_vport *vport); + +#endif /* SCSI_TRANSPORT_FC_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_iscsi.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_iscsi.h.svn-base new file mode 100644 index 00000000..b50aabe2 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_iscsi.h.svn-base @@ -0,0 +1,255 @@ +/* + * iSCSI transport class definitions + * + * Copyright (C) IBM Corporation, 2004 + * Copyright (C) Mike Christie, 2004 - 2006 + * Copyright (C) Dmitry Yusupov, 2004 - 2005 + * Copyright (C) Alex Aizman, 2004 - 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef SCSI_TRANSPORT_ISCSI_H +#define SCSI_TRANSPORT_ISCSI_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <scsi/iscsi_if.h> + +struct scsi_transport_template; +struct iscsi_transport; +struct iscsi_endpoint; +struct Scsi_Host; +struct iscsi_cls_conn; +struct iscsi_conn; +struct iscsi_task; +struct sockaddr; + +/** + * struct iscsi_transport - iSCSI Transport template + * + * @name: transport name + * @caps: iSCSI Data-Path capabilities + * @create_session: create new iSCSI session object + * @destroy_session: destroy existing iSCSI session object + * @create_conn: create new iSCSI connection + * @bind_conn: associate this connection with existing iSCSI session + * and specified transport descriptor + * @destroy_conn: destroy inactive iSCSI connection + * @set_param: set iSCSI parameter. Return 0 on success, -ENODATA + * when param is not supported, and a -Exx value on other + * error. + * @get_param get iSCSI parameter. Must return number of bytes + * copied to buffer on success, -ENODATA when param + * is not supported, and a -Exx value on other error + * @start_conn: set connection to be operational + * @stop_conn: suspend/recover/terminate connection + * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. + * @session_recovery_timedout: notify LLD a block during recovery timed out + * @init_task: Initialize a iscsi_task and any internal structs. + * When offloading the data path, this is called from + * queuecommand with the session lock, or from the + * iscsi_conn_send_pdu context with the session lock. + * When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @xmit_task Requests LLD to transfer cmd task. Returns 0 or the + * the number of bytes transferred on success, and -Exyz + * value on error. When offloading the data path, this + * is called from queuecommand with the session lock, or + * from the iscsi_conn_send_pdu context with the session + * lock. When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @cleanup_task: requests LLD to fail task. Called with session lock + * and after the connection has been suspended and + * terminated during recovery. If called + * from abort task then connection is not suspended + * or terminated but sk_callback_lock is held + * + * Template API provided by iSCSI Transport + */ +struct iscsi_transport { + struct module *owner; + char *name; + unsigned int caps; + /* LLD sets this to indicate what values it can export to sysfs */ + uint64_t param_mask; + uint64_t host_param_mask; + struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep, + uint16_t cmds_max, uint16_t qdepth, + uint32_t sn, uint32_t *hn); + void (*destroy_session) (struct iscsi_cls_session *session); + struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, + uint32_t cid); + int (*bind_conn) (struct iscsi_cls_session *session, + struct iscsi_cls_conn *cls_conn, + uint64_t transport_eph, int is_leading); + int (*start_conn) (struct iscsi_cls_conn *conn); + void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); + void (*destroy_conn) (struct iscsi_cls_conn *conn); + int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, + char *buf, int buflen); + int (*get_conn_param) (struct iscsi_cls_conn *conn, + enum iscsi_param param, char *buf); + int (*get_session_param) (struct iscsi_cls_session *session, + enum iscsi_param param, char *buf); + int (*get_host_param) (struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf); + int (*set_host_param) (struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf, + int buflen); + int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); + void (*get_stats) (struct iscsi_cls_conn *conn, + struct iscsi_stats *stats); + + int (*init_task) (struct iscsi_task *task); + int (*xmit_task) (struct iscsi_task *task); + void (*cleanup_task) (struct iscsi_task *task); + + int (*alloc_pdu) (struct iscsi_task *task, uint8_t opcode); + int (*xmit_pdu) (struct iscsi_task *task); + int (*init_pdu) (struct iscsi_task *task, unsigned int offset, + unsigned int count); + void (*parse_pdu_itt) (struct iscsi_conn *conn, itt_t itt, + int *index, int *age); + + void (*session_recovery_timedout) (struct iscsi_cls_session *session); + struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, + int non_blocking); + int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms); + void (*ep_disconnect) (struct iscsi_endpoint *ep); + int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type, + uint32_t enable, struct sockaddr *dst_addr); +}; + +/* + * transport registration upcalls + */ +extern struct scsi_transport_template *iscsi_register_transport(struct iscsi_transport *tt); +extern int iscsi_unregister_transport(struct iscsi_transport *tt); + +/* + * control plane upcalls + */ +extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn, + enum iscsi_err error); +extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); + +struct iscsi_cls_conn { + struct list_head conn_list; /* item in connlist */ + void *dd_data; /* LLD private data */ + struct iscsi_transport *transport; + uint32_t cid; /* connection id */ + + int active; /* must be accessed with the connlock */ + struct device dev; /* sysfs transport/container device */ +}; + +#define iscsi_dev_to_conn(_dev) \ + container_of(_dev, struct iscsi_cls_conn, dev) + +#define iscsi_conn_to_session(_conn) \ + iscsi_dev_to_session(_conn->dev.parent) + +/* iscsi class session state */ +enum { + ISCSI_SESSION_LOGGED_IN, + ISCSI_SESSION_FAILED, + ISCSI_SESSION_FREE, +}; + +#define ISCSI_MAX_TARGET -1 + +struct iscsi_cls_session { + struct list_head sess_list; /* item in session_list */ + struct iscsi_transport *transport; + spinlock_t lock; + struct work_struct block_work; + struct work_struct unblock_work; + struct work_struct scan_work; + struct work_struct unbind_work; + + /* recovery fields */ + int recovery_tmo; + struct delayed_work recovery_work; + + unsigned int target_id; + + int state; + int sid; /* session id */ + void *dd_data; /* LLD private data */ + struct device dev; /* sysfs transport/container device */ +}; + +#define iscsi_dev_to_session(_dev) \ + container_of(_dev, struct iscsi_cls_session, dev) + +#define iscsi_session_to_shost(_session) \ + dev_to_shost(_session->dev.parent) + +#define starget_to_session(_stgt) \ + iscsi_dev_to_session(_stgt->dev.parent) + +struct iscsi_cls_host { + atomic_t nr_scans; + struct mutex mutex; + struct workqueue_struct *scan_workq; + char scan_workq_name[20]; +}; + +extern void iscsi_host_for_each_session(struct Scsi_Host *shost, + void (*fn)(struct iscsi_cls_session *)); + +struct iscsi_endpoint { + void *dd_data; /* LLD private data */ + struct device dev; + uint64_t id; +}; + +/* + * session and connection functions that can be used by HW iSCSI LLDs + */ +#define iscsi_cls_session_printk(prefix, _cls_session, fmt, a...) \ + dev_printk(prefix, &(_cls_session)->dev, fmt, ##a) + +#define iscsi_cls_conn_printk(prefix, _cls_conn, fmt, a...) \ + dev_printk(prefix, &(_cls_conn)->dev, fmt, ##a) + +extern int iscsi_session_chkready(struct iscsi_cls_session *session); +extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, + struct iscsi_transport *transport, int dd_size); +extern int iscsi_add_session(struct iscsi_cls_session *session, + unsigned int target_id); +extern int iscsi_session_event(struct iscsi_cls_session *session, + enum iscsi_uevent_e event); +extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, + struct iscsi_transport *t, + int dd_size, + unsigned int target_id); +extern void iscsi_remove_session(struct iscsi_cls_session *session); +extern void iscsi_free_session(struct iscsi_cls_session *session); +extern int iscsi_destroy_session(struct iscsi_cls_session *session); +extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, + int dd_size, uint32_t cid); +extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); +extern void iscsi_unblock_session(struct iscsi_cls_session *session); +extern void iscsi_block_session(struct iscsi_cls_session *session); +extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time); +extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size); +extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep); +extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle); + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_sas.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_sas.h.svn-base new file mode 100644 index 00000000..61ad3594 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_sas.h.svn-base @@ -0,0 +1,220 @@ +#ifndef SCSI_TRANSPORT_SAS_H +#define SCSI_TRANSPORT_SAS_H + +#include <linux/transport_class.h> +#include <linux/types.h> +#include <linux/mutex.h> +#include <scsi/sas.h> + +struct scsi_transport_template; +struct sas_rphy; +struct request; + +enum sas_device_type { + SAS_PHY_UNUSED = 0, + SAS_END_DEVICE = 1, + SAS_EDGE_EXPANDER_DEVICE = 2, + SAS_FANOUT_EXPANDER_DEVICE = 3, +}; + +static inline int sas_protocol_ata(enum sas_protocol proto) +{ + return ((proto & SAS_PROTOCOL_SATA) || + (proto & SAS_PROTOCOL_STP))? 1 : 0; +} + +enum sas_linkrate { + /* These Values are defined in the SAS standard */ + SAS_LINK_RATE_UNKNOWN = 0, + SAS_PHY_DISABLED = 1, + SAS_PHY_RESET_PROBLEM = 2, + SAS_SATA_SPINUP_HOLD = 3, + SAS_SATA_PORT_SELECTOR = 4, + SAS_PHY_RESET_IN_PROGRESS = 5, + SAS_LINK_RATE_1_5_GBPS = 8, + SAS_LINK_RATE_G1 = SAS_LINK_RATE_1_5_GBPS, + SAS_LINK_RATE_3_0_GBPS = 9, + SAS_LINK_RATE_G2 = SAS_LINK_RATE_3_0_GBPS, + SAS_LINK_RATE_6_0_GBPS = 10, + /* These are virtual to the transport class and may never + * be signalled normally since the standard defined field + * is only 4 bits */ + SAS_LINK_RATE_FAILED = 0x10, + SAS_PHY_VIRTUAL = 0x11, +}; + +struct sas_identify { + enum sas_device_type device_type; + enum sas_protocol initiator_port_protocols; + enum sas_protocol target_port_protocols; + u64 sas_address; + u8 phy_identifier; +}; + +struct sas_phy { + struct device dev; + int number; + int enabled; + + /* phy identification */ + struct sas_identify identify; + + /* phy attributes */ + enum sas_linkrate negotiated_linkrate; + enum sas_linkrate minimum_linkrate_hw; + enum sas_linkrate minimum_linkrate; + enum sas_linkrate maximum_linkrate_hw; + enum sas_linkrate maximum_linkrate; + + /* link error statistics */ + u32 invalid_dword_count; + u32 running_disparity_error_count; + u32 loss_of_dword_sync_count; + u32 phy_reset_problem_count; + + /* for the list of phys belonging to a port */ + struct list_head port_siblings; + + struct work_struct reset_work; +}; + +#define dev_to_phy(d) \ + container_of((d), struct sas_phy, dev) +#define transport_class_to_phy(dev) \ + dev_to_phy((dev)->parent) +#define phy_to_shost(phy) \ + dev_to_shost((phy)->dev.parent) + +struct request_queue; +struct sas_rphy { + struct device dev; + struct sas_identify identify; + struct list_head list; + struct request_queue *q; + u32 scsi_target_id; +}; + +#define dev_to_rphy(d) \ + container_of((d), struct sas_rphy, dev) +#define transport_class_to_rphy(dev) \ + dev_to_rphy((dev)->parent) +#define rphy_to_shost(rphy) \ + dev_to_shost((rphy)->dev.parent) +#define target_to_rphy(targ) \ + dev_to_rphy((targ)->dev.parent) + +struct sas_end_device { + struct sas_rphy rphy; + /* flags */ + unsigned ready_led_meaning:1; + /* parameters */ + u16 I_T_nexus_loss_timeout; + u16 initiator_response_timeout; +}; +#define rphy_to_end_device(r) \ + container_of((r), struct sas_end_device, rphy) + +struct sas_expander_device { + int level; + int next_port_id; + + #define SAS_EXPANDER_VENDOR_ID_LEN 8 + char vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1]; + #define SAS_EXPANDER_PRODUCT_ID_LEN 16 + char product_id[SAS_EXPANDER_PRODUCT_ID_LEN+1]; + #define SAS_EXPANDER_PRODUCT_REV_LEN 4 + char product_rev[SAS_EXPANDER_PRODUCT_REV_LEN+1]; + #define SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN 8 + char component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN+1]; + u16 component_id; + u8 component_revision_id; + + struct sas_rphy rphy; + +}; +#define rphy_to_expander_device(r) \ + container_of((r), struct sas_expander_device, rphy) + +struct sas_port { + struct device dev; + + int port_identifier; + int num_phys; + /* port flags */ + unsigned int is_backlink:1; + + /* the other end of the link */ + struct sas_rphy *rphy; + + struct mutex phy_list_mutex; + struct list_head phy_list; +}; + +#define dev_to_sas_port(d) \ + container_of((d), struct sas_port, dev) +#define transport_class_to_sas_port(dev) \ + dev_to_sas_port((dev)->parent) + +struct sas_phy_linkrates { + enum sas_linkrate maximum_linkrate; + enum sas_linkrate minimum_linkrate; +}; + +/* The functions by which the transport class and the driver communicate */ +struct sas_function_template { + int (*get_linkerrors)(struct sas_phy *); + int (*get_enclosure_identifier)(struct sas_rphy *, u64 *); + int (*get_bay_identifier)(struct sas_rphy *); + int (*phy_reset)(struct sas_phy *, int); + int (*phy_enable)(struct sas_phy *, int); + int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); + int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); +}; + + +void sas_remove_children(struct device *); +extern void sas_remove_host(struct Scsi_Host *); + +extern struct sas_phy *sas_phy_alloc(struct device *, int); +extern void sas_phy_free(struct sas_phy *); +extern int sas_phy_add(struct sas_phy *); +extern void sas_phy_delete(struct sas_phy *); +extern int scsi_is_sas_phy(const struct device *); + +extern struct sas_rphy *sas_end_device_alloc(struct sas_port *); +extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); +void sas_rphy_free(struct sas_rphy *); +extern int sas_rphy_add(struct sas_rphy *); +extern void sas_rphy_remove(struct sas_rphy *); +extern void sas_rphy_delete(struct sas_rphy *); +extern int scsi_is_sas_rphy(const struct device *); + +struct sas_port *sas_port_alloc(struct device *, int); +struct sas_port *sas_port_alloc_num(struct device *); +int sas_port_add(struct sas_port *); +void sas_port_free(struct sas_port *); +void sas_port_delete(struct sas_port *); +void sas_port_add_phy(struct sas_port *, struct sas_phy *); +void sas_port_delete_phy(struct sas_port *, struct sas_phy *); +void sas_port_mark_backlink(struct sas_port *); +int scsi_is_sas_port(const struct device *); + +extern struct scsi_transport_template * +sas_attach_transport(struct sas_function_template *); +extern void sas_release_transport(struct scsi_transport_template *); +int sas_read_port_mode_page(struct scsi_device *); + +static inline int +scsi_is_sas_expander_device(struct device *dev) +{ + struct sas_rphy *rphy; + if (!scsi_is_sas_rphy(dev)) + return 0; + rphy = dev_to_rphy(dev); + return rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE || + rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE; +} + +#define scsi_is_sas_phy_local(phy) scsi_is_host_device((phy)->dev.parent) + +#endif /* SCSI_TRANSPORT_SAS_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_spi.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_spi.h.svn-base new file mode 100644 index 00000000..286e9628 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_spi.h.svn-base @@ -0,0 +1,157 @@ +/* + * Parallel SCSI (SPI) transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef SCSI_TRANSPORT_SPI_H +#define SCSI_TRANSPORT_SPI_H + +#include <linux/transport_class.h> +#include <linux/mutex.h> + +struct scsi_transport_template; +struct scsi_target; +struct scsi_device; +struct Scsi_Host; + +struct spi_transport_attrs { + int period; /* value in the PPR/SDTR command */ + int min_period; + int offset; + int max_offset; + unsigned int width:1; /* 0 - narrow, 1 - wide */ + unsigned int max_width:1; + unsigned int iu:1; /* Information Units enabled */ + unsigned int dt:1; /* DT clocking enabled */ + unsigned int qas:1; /* Quick Arbitration and Selection enabled */ + unsigned int wr_flow:1; /* Write Flow control enabled */ + unsigned int rd_strm:1; /* Read streaming enabled */ + unsigned int rti:1; /* Retain Training Information */ + unsigned int pcomp_en:1;/* Precompensation enabled */ + unsigned int hold_mcs:1;/* Hold Margin Control Settings */ + unsigned int initial_dv:1; /* DV done to this target yet */ + unsigned long flags; /* flags field for drivers to use */ + /* Device Properties fields */ + unsigned int support_sync:1; /* synchronous support */ + unsigned int support_wide:1; /* wide support */ + unsigned int support_dt:1; /* allows DT phases */ + unsigned int support_dt_only; /* disallows ST phases */ + unsigned int support_ius; /* support Information Units */ + unsigned int support_qas; /* supports quick arbitration and selection */ + /* Private Fields */ + unsigned int dv_pending:1; /* Internal flag: DV Requested */ + unsigned int dv_in_progress:1; /* Internal: DV started */ + struct mutex dv_mutex; /* semaphore to serialise dv */ +}; + +enum spi_signal_type { + SPI_SIGNAL_UNKNOWN = 1, + SPI_SIGNAL_SE, + SPI_SIGNAL_LVD, + SPI_SIGNAL_HVD, +}; + +struct spi_host_attrs { + enum spi_signal_type signalling; +}; + +/* accessor functions */ +#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) +#define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period) +#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) +#define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset) +#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) +#define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width) +#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) +#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) +#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) +#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->starget_data)->wr_flow) +#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rd_strm) +#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rti) +#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) +#define spi_hold_mcs(x) (((struct spi_transport_attrs *)&(x)->starget_data)->hold_mcs) +#define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) +#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) + +#define spi_support_sync(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_sync) +#define spi_support_wide(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_wide) +#define spi_support_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt) +#define spi_support_dt_only(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt_only) +#define spi_support_ius(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_ius) +#define spi_support_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_qas) + +#define spi_flags(x) (((struct spi_transport_attrs *)&(x)->starget_data)->flags) +#define spi_signalling(h) (((struct spi_host_attrs *)(h)->shost_data)->signalling) + + + +/* The functions by which the transport class and the driver communicate */ +struct spi_function_template { + void (*get_period)(struct scsi_target *); + void (*set_period)(struct scsi_target *, int); + void (*get_offset)(struct scsi_target *); + void (*set_offset)(struct scsi_target *, int); + void (*get_width)(struct scsi_target *); + void (*set_width)(struct scsi_target *, int); + void (*get_iu)(struct scsi_target *); + void (*set_iu)(struct scsi_target *, int); + void (*get_dt)(struct scsi_target *); + void (*set_dt)(struct scsi_target *, int); + void (*get_qas)(struct scsi_target *); + void (*set_qas)(struct scsi_target *, int); + void (*get_wr_flow)(struct scsi_target *); + void (*set_wr_flow)(struct scsi_target *, int); + void (*get_rd_strm)(struct scsi_target *); + void (*set_rd_strm)(struct scsi_target *, int); + void (*get_rti)(struct scsi_target *); + void (*set_rti)(struct scsi_target *, int); + void (*get_pcomp_en)(struct scsi_target *); + void (*set_pcomp_en)(struct scsi_target *, int); + void (*get_hold_mcs)(struct scsi_target *); + void (*set_hold_mcs)(struct scsi_target *, int); + void (*get_signalling)(struct Scsi_Host *); + void (*set_signalling)(struct Scsi_Host *, enum spi_signal_type); + int (*deny_binding)(struct scsi_target *); + /* The driver sets these to tell the transport class it + * wants the attributes displayed in sysfs. If the show_ flag + * is not set, the attribute will be private to the transport + * class */ + unsigned long show_period:1; + unsigned long show_offset:1; + unsigned long show_width:1; + unsigned long show_iu:1; + unsigned long show_dt:1; + unsigned long show_qas:1; + unsigned long show_wr_flow:1; + unsigned long show_rd_strm:1; + unsigned long show_rti:1; + unsigned long show_pcomp_en:1; + unsigned long show_hold_mcs:1; +}; + +struct scsi_transport_template *spi_attach_transport(struct spi_function_template *); +void spi_release_transport(struct scsi_transport_template *); +void spi_schedule_dv_device(struct scsi_device *); +void spi_dv_device(struct scsi_device *); +void spi_display_xfer_agreement(struct scsi_target *); +int spi_print_msg(const unsigned char *); +int spi_populate_width_msg(unsigned char *msg, int width); +int spi_populate_sync_msg(unsigned char *msg, int period, int offset); +int spi_populate_ppr_msg(unsigned char *msg, int period, int offset, int width, + int options); + +#endif /* SCSI_TRANSPORT_SPI_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_srp.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_srp.h.svn-base new file mode 100644 index 00000000..9c60ca1c --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsi_transport_srp.h.svn-base @@ -0,0 +1,39 @@ +#ifndef SCSI_TRANSPORT_SRP_H +#define SCSI_TRANSPORT_SRP_H + +#include <linux/transport_class.h> +#include <linux/types.h> +#include <linux/mutex.h> + +#define SRP_RPORT_ROLE_INITIATOR 0 +#define SRP_RPORT_ROLE_TARGET 1 + +struct srp_rport_identifiers { + u8 port_id[16]; + u8 roles; +}; + +struct srp_rport { + struct device dev; + + u8 port_id[16]; + u8 roles; +}; + +struct srp_function_template { + /* for target drivers */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); +}; + +extern struct scsi_transport_template * +srp_attach_transport(struct srp_function_template *); +extern void srp_release_transport(struct scsi_transport_template *); + +extern struct srp_rport *srp_rport_add(struct Scsi_Host *, + struct srp_rport_identifiers *); +extern void srp_rport_del(struct srp_rport *); + +extern void srp_remove_host(struct Scsi_Host *); + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/scsicam.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsicam.h.svn-base new file mode 100644 index 00000000..24ede474 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/scsicam.h.svn-base @@ -0,0 +1,19 @@ +/* + * scsicam.h - SCSI CAM support functions, use for HDIO_GETGEO, etc. + * + * Copyright 1993, 1994 Drew Eckhardt + * Visionary Computing + * (Unix and Linux consulting and custom programming) + * drew@Colorado.EDU + * +1 (303) 786-7975 + * + * For more information, please consult the SCSI-CAM draft. + */ + +#ifndef SCSICAM_H +#define SCSICAM_H +extern int scsicam_bios_param (struct block_device *bdev, sector_t capacity, int *ip); +extern int scsi_partsize(unsigned char *buf, unsigned long capacity, + unsigned int *cyls, unsigned int *hds, unsigned int *secs); +extern unsigned char *scsi_bios_ptable(struct block_device *bdev); +#endif /* def SCSICAM_H */ diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/sg.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/sg.h.svn-base new file mode 100644 index 00000000..934ae389 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/sg.h.svn-base @@ -0,0 +1,308 @@ +#ifndef _SCSI_GENERIC_H +#define _SCSI_GENERIC_H + +#include <linux/compiler.h> + +/* + History: + Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user + process control of SCSI devices. + Development Sponsored by Killy Corp. NY NY +Original driver (sg.h): +* Copyright (C) 1992 Lawrence Foard +Version 2 and 3 extensions to driver: +* Copyright (C) 1998 - 2006 Douglas Gilbert + + Version: 3.5.34 (20060920) + This version is for 2.6 series kernels. + + For a full changelog see http://www.torque.net/sg + +Map of SG verions to the Linux kernels in which they appear: + ---------- ---------------------------------- + original all kernels < 2.2.6 + 2.1.40 2.2.20 + 3.0.x optional version 3 sg driver for 2.2 series + 3.1.17++ 2.4.0++ + 3.5.30++ 2.6.0++ + +Major new features in SG 3.x driver (cf SG 2.x drivers) + - SG_IO ioctl() combines function if write() and read() + - new interface (sg_io_hdr_t) but still supports old interface + - scatter/gather in user space, direct IO, and mmap supported + + The normal action of this driver is to use the adapter (HBA) driver to DMA + data into kernel buffers and then use the CPU to copy the data into the + user space (vice versa for writes). That is called "indirect" IO due to + the double handling of data. There are two methods offered to remove the + redundant copy: 1) direct IO and 2) using the mmap() system call to map + the reserve buffer (this driver has one reserve buffer per fd) into the + user space. Both have their advantages. + In terms of absolute speed mmap() is faster. If speed is not a concern, + indirect IO should be fine. Read the documentation for more information. + + ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or + 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed. + That attribute is 0 by default. ** + + Historical note: this SCSI pass-through driver has been known as "sg" for + a decade. In broader kernel discussions "sg" is used to refer to scatter + gather techniques. The context should clarify which "sg" is referred to. + + Documentation + ============= + A web site for the SG device driver can be found at: + http://www.torque.net/sg [alternatively check the MAINTAINERS file] + The documentation for the sg version 3 driver can be found at: + http://www.torque.net/sg/p/sg_v3_ho.html + This is a rendering from DocBook source [change the extension to "sgml" + or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). + The SG_IO ioctl is now found in other parts kernel (e.g. the block layer). + For more information see http://www.torque.net/sg/sg_io.html + + The older, version 2 documents discuss the original sg interface in detail: + http://www.torque.net/sg/p/scsi-generic.txt + http://www.torque.net/sg/p/scsi-generic_long.txt + Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt + + Utility and test programs are available at the sg web site. They are + packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils + (for the lk 2.2 series). +*/ + + +/* New interface introduced in the 3.x SG drivers follows */ + +typedef struct sg_iovec /* same structure as used by readv() Linux system */ +{ /* call. It defines one scatter-gather element. */ + void __user *iov_base; /* Starting address */ + size_t iov_len; /* Length in bytes */ +} sg_iovec_t; + + +typedef struct sg_io_hdr +{ + int interface_id; /* [i] 'S' for SCSI generic (required) */ + int dxfer_direction; /* [i] data transfer direction */ + unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ + unsigned char mx_sb_len; /* [i] max length to write to sbp */ + unsigned short iovec_count; /* [i] 0 implies no scatter gather */ + unsigned int dxfer_len; /* [i] byte count of data transfer */ + void __user *dxferp; /* [i], [*io] points to data transfer memory + or scatter gather list */ + unsigned char __user *cmdp; /* [i], [*i] points to command to perform */ + void __user *sbp; /* [i], [*o] points to sense_buffer memory */ + unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ + unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */ + int pack_id; /* [i->o] unused internally (normally) */ + void __user * usr_ptr; /* [i->o] unused internally */ + unsigned char status; /* [o] scsi status */ + unsigned char masked_status;/* [o] shifted, masked scsi status */ + unsigned char msg_status; /* [o] messaging level data (optional) */ + unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ + unsigned short host_status; /* [o] errors from host adapter */ + unsigned short driver_status;/* [o] errors from software driver */ + int resid; /* [o] dxfer_len - actual_transferred */ + unsigned int duration; /* [o] time taken by cmd (unit: millisec) */ + unsigned int info; /* [o] auxiliary information */ +} sg_io_hdr_t; /* 64 bytes long (on i386) */ + +#define SG_INTERFACE_ID_ORIG 'S' + +/* Use negative values to flag difference from original sg_header structure */ +#define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */ +#define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */ +#define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */ +#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the + additional property than during indirect + IO the user buffer is copied into the + kernel buffers before the transfer */ +#define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */ + +/* following flag values can be "or"-ed together */ +#define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */ +#define SG_FLAG_UNUSED_LUN_INHIBIT 2 /* default is overwrite lun in SCSI */ + /* command block (when <= SCSI_2) */ +#define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */ +#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */ + /* user space (debug indirect IO) */ + +/* following 'info' values are "or"-ed together */ +#define SG_INFO_OK_MASK 0x1 +#define SG_INFO_OK 0x0 /* no sense, host nor driver "noise" */ +#define SG_INFO_CHECK 0x1 /* something abnormal happened */ + +#define SG_INFO_DIRECT_IO_MASK 0x6 +#define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */ +#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */ +#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */ + + +typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */ + int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */ + int channel; + int scsi_id; /* scsi id of target device */ + int lun; + int scsi_type; /* TYPE_... defined in scsi/scsi.h */ + short h_cmd_per_lun;/* host (adapter) maximum commands per lun */ + short d_queue_depth;/* device (or adapter) maximum queue length */ + int unused[2]; /* probably find a good use, set 0 for now */ +} sg_scsi_id_t; /* 32 bytes long on i386 */ + +typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ + char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */ + char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */ + char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */ + char problem; /* 0 -> no problem detected, 1 -> error to report */ + int pack_id; /* pack_id associated with request */ + void __user *usr_ptr; /* user provided pointer (in new interface) */ + unsigned int duration; /* millisecs elapsed since written (req_state==1) + or request duration (req_state==2) */ + int unused; +} sg_req_info_t; /* 20 bytes long on i386 */ + + +/* IOCTLs: Those ioctls that are relevant to the SG 3.x drivers follow. + [Those that only apply to the SG 2.x drivers are at the end of the file.] + (_GET_s yield result via 'int *' 3rd argument unless otherwise indicated) */ + +#define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */ + +/* Used to configure SCSI command transformation layer for ATAPI devices */ +/* Only supported by the ide-scsi driver */ +#define SG_SET_TRANSFORM 0x2204 /* N.B. 3rd arg is not pointer but value: */ + /* 3rd arg = 0 to disable transform, 1 to enable it */ +#define SG_GET_TRANSFORM 0x2205 + +#define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */ +#define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */ + +/* The following ioctl has a 'sg_scsi_id_t *' object as its 3rd argument. */ +#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */ +/* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */ + +/* Override host setting and always DMA using low memory ( <16MB on i386) */ +#define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */ +#define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */ + +/* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which + tries to fetch a packet with a matching pack_id, waits, or returns EAGAIN. + If pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0 + then pack_id ignored by read() and oldest readable fetched. */ +#define SG_SET_FORCE_PACK_ID 0x227b +#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */ + +#define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */ + +/* Yields max scatter gather tablesize allowed by current host adapter */ +#define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */ + +#define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */ + +/* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */ +#define SG_SCSI_RESET 0x2284 +/* Associated values that can be given to SG_SCSI_RESET follow */ +#define SG_SCSI_RESET_NOTHING 0 +#define SG_SCSI_RESET_DEVICE 1 +#define SG_SCSI_RESET_BUS 2 +#define SG_SCSI_RESET_HOST 3 +#define SG_SCSI_RESET_TARGET 4 + +/* synchronous SCSI command ioctl, (only in version 3 interface) */ +#define SG_IO 0x2285 /* similar effect as write() followed by read() */ + +#define SG_GET_REQUEST_TABLE 0x2286 /* yields table of active requests */ + +/* How to treat EINTR during SG_IO ioctl(), only in SG 3.x series */ +#define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */ +#define SG_GET_KEEP_ORPHAN 0x2288 + +/* yields scsi midlevel's access_count for this SCSI device */ +#define SG_GET_ACCESS_COUNT 0x2289 + + +#define SG_SCATTER_SZ (8 * 4096) +/* Largest size (in bytes) a single scatter-gather list element can have. + The value used by the driver is 'max(SG_SCATTER_SZ, PAGE_SIZE)'. + This value should be a power of 2 (and may be rounded up internally). + If scatter-gather is not supported by adapter then this value is the + largest data block that can be read/written by a single scsi command. */ + +#define SG_DEFAULT_RETRIES 0 + +/* Defaults, commented if they differ from original sg driver */ +#define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */ +#define SG_DEF_FORCE_PACK_ID 0 +#define SG_DEF_KEEP_ORPHAN 0 +#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ /* load time option */ + +/* maximum outstanding requests, write() yields EDOM if exceeded */ +#define SG_MAX_QUEUE 16 + +#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */ + +/* Alternate style type names, "..._t" variants preferred */ +typedef struct sg_io_hdr Sg_io_hdr; +typedef struct sg_io_vec Sg_io_vec; +typedef struct sg_scsi_id Sg_scsi_id; +typedef struct sg_req_info Sg_req_info; + + +/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +/* The older SG interface based on the 'sg_header' structure follows. */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + +#define SG_MAX_SENSE 16 /* this only applies to the sg_header interface */ + +struct sg_header +{ + int pack_len; /* [o] reply_len (ie useless), ignored as input */ + int reply_len; /* [i] max length of expected reply (inc. sg_header) */ + int pack_id; /* [io] id number of packet (use ints >= 0) */ + int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */ + unsigned int twelve_byte:1; + /* [i] Force 12 byte command length for group 6 & 7 commands */ + unsigned int target_status:5; /* [o] scsi status from target */ + unsigned int host_status:8; /* [o] host status (see "DID" codes) */ + unsigned int driver_status:8; /* [o] driver status+suggestion */ + unsigned int other_flags:10; /* unused */ + unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases: + when target_status is CHECK_CONDITION or + when target_status is COMMAND_TERMINATED or + when (driver_status & DRIVER_SENSE) is true. */ +}; /* This structure is 36 bytes long on i386 */ + + +/* IOCTLs: The following are not required (or ignored) when the sg_io_hdr_t + interface is used. They are kept for backward compatibility with + the original and version 2 drivers. */ + +#define SG_SET_TIMEOUT 0x2201 /* unit: jiffies (10ms on i386) */ +#define SG_GET_TIMEOUT 0x2202 /* yield timeout as _return_ value */ + +/* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q. + Each time a sg_io_hdr_t object is seen on this file descriptor, this + command queuing flag is set on (overriding the previous setting). */ +#define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on) */ +#define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1 */ + +/* Turn on/off error sense trace (1 and 0 respectively, default is off). + Try using: "# cat /proc/scsi/sg/debug" instead in the v3 driver */ +#define SG_SET_DEBUG 0x227e /* 0 -> turn off debug */ + +#define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given + number on the next write() on this file descriptor */ + + +/* Defaults, commented if they differ from original sg driver */ +#ifdef __KERNEL__ +#define SG_DEFAULT_TIMEOUT_USER (60*USER_HZ) /* HZ == 'jiffies in 1 second' */ +#else +#define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */ +#endif + +#define SG_DEF_COMMAND_Q 0 /* command queuing is always on when + the new interface is used */ +#define SG_DEF_UNDERRUN_FLAG 0 + +#endif diff --git a/libdde_linux26/contrib/include/scsi/.svn/text-base/srp.h.svn-base b/libdde_linux26/contrib/include/scsi/.svn/text-base/srp.h.svn-base new file mode 100644 index 00000000..ad178fa7 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/.svn/text-base/srp.h.svn-base @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2005 Cisco Systems. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * $Id$ + */ + +#ifndef SCSI_SRP_H +#define SCSI_SRP_H + +/* + * Structures and constants for the SCSI RDMA Protocol (SRP) as + * defined by the INCITS T10 committee. This file was written using + * draft Revision 16a of the SRP standard. + */ + +#include <linux/types.h> + +enum { + SRP_LOGIN_REQ = 0x00, + SRP_TSK_MGMT = 0x01, + SRP_CMD = 0x02, + SRP_I_LOGOUT = 0x03, + SRP_LOGIN_RSP = 0xc0, + SRP_RSP = 0xc1, + SRP_LOGIN_REJ = 0xc2, + SRP_T_LOGOUT = 0x80, + SRP_CRED_REQ = 0x81, + SRP_AER_REQ = 0x82, + SRP_CRED_RSP = 0x41, + SRP_AER_RSP = 0x42 +}; + +enum { + SRP_BUF_FORMAT_DIRECT = 1 << 1, + SRP_BUF_FORMAT_INDIRECT = 1 << 2 +}; + +enum { + SRP_NO_DATA_DESC = 0, + SRP_DATA_DESC_DIRECT = 1, + SRP_DATA_DESC_INDIRECT = 2 +}; + +enum { + SRP_TSK_ABORT_TASK = 0x01, + SRP_TSK_ABORT_TASK_SET = 0x02, + SRP_TSK_CLEAR_TASK_SET = 0x04, + SRP_TSK_LUN_RESET = 0x08, + SRP_TSK_CLEAR_ACA = 0x40 +}; + +enum srp_login_rej_reason { + SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL = 0x00010000, + SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES = 0x00010001, + SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002, + SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL = 0x00010003, + SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004, + SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED = 0x00010005, + SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED = 0x00010006 +}; + +enum { + SRP_REV10_IB_IO_CLASS = 0xff00, + SRP_REV16A_IB_IO_CLASS = 0x0100 +}; + +struct srp_direct_buf { + __be64 va; + __be32 key; + __be32 len; +}; + +/* + * We need the packed attribute because the SRP spec puts the list of + * descriptors at an offset of 20, which is not aligned to the size of + * struct srp_direct_buf. The whole structure must be packed to avoid + * having the 20-byte structure padded to 24 bytes on 64-bit architectures. + */ +struct srp_indirect_buf { + struct srp_direct_buf table_desc; + __be32 len; + struct srp_direct_buf desc_list[0]; +} __attribute__((packed)); + +enum { + SRP_MULTICHAN_SINGLE = 0, + SRP_MULTICHAN_MULTI = 1 +}; + +struct srp_login_req { + u8 opcode; + u8 reserved1[7]; + u64 tag; + __be32 req_it_iu_len; + u8 reserved2[4]; + __be16 req_buf_fmt; + u8 req_flags; + u8 reserved3[5]; + u8 initiator_port_id[16]; + u8 target_port_id[16]; +}; + +/* + * The SRP spec defines the size of the LOGIN_RSP structure to be 52 + * bytes, so it needs to be packed to avoid having it padded to 56 + * bytes on 64-bit architectures. + */ +struct srp_login_rsp { + u8 opcode; + u8 reserved1[3]; + __be32 req_lim_delta; + u64 tag; + __be32 max_it_iu_len; + __be32 max_ti_iu_len; + __be16 buf_fmt; + u8 rsp_flags; + u8 reserved2[25]; +} __attribute__((packed)); + +struct srp_login_rej { + u8 opcode; + u8 reserved1[3]; + __be32 reason; + u64 tag; + u8 reserved2[8]; + __be16 buf_fmt; + u8 reserved3[6]; +}; + +struct srp_i_logout { + u8 opcode; + u8 reserved[7]; + u64 tag; +}; + +struct srp_t_logout { + u8 opcode; + u8 sol_not; + u8 reserved[2]; + __be32 reason; + u64 tag; +}; + +/* + * We need the packed attribute because the SRP spec only aligns the + * 8-byte LUN field to 4 bytes. + */ +struct srp_tsk_mgmt { + u8 opcode; + u8 sol_not; + u8 reserved1[6]; + u64 tag; + u8 reserved2[4]; + __be64 lun __attribute__((packed)); + u8 reserved3[2]; + u8 tsk_mgmt_func; + u8 reserved4; + u64 task_tag; + u8 reserved5[8]; +}; + +/* + * We need the packed attribute because the SRP spec only aligns the + * 8-byte LUN field to 4 bytes. + */ +struct srp_cmd { + u8 opcode; + u8 sol_not; + u8 reserved1[3]; + u8 buf_fmt; + u8 data_out_desc_cnt; + u8 data_in_desc_cnt; + u64 tag; + u8 reserved2[4]; + __be64 lun __attribute__((packed)); + u8 reserved3; + u8 task_attr; + u8 reserved4; + u8 add_cdb_len; + u8 cdb[16]; + u8 add_data[0]; +}; + +enum { + SRP_RSP_FLAG_RSPVALID = 1 << 0, + SRP_RSP_FLAG_SNSVALID = 1 << 1, + SRP_RSP_FLAG_DOOVER = 1 << 2, + SRP_RSP_FLAG_DOUNDER = 1 << 3, + SRP_RSP_FLAG_DIOVER = 1 << 4, + SRP_RSP_FLAG_DIUNDER = 1 << 5 +}; + +/* + * The SRP spec defines the size of the RSP structure to be 36 bytes, + * so it needs to be packed to avoid having it padded to 40 bytes on + * 64-bit architectures. + */ +struct srp_rsp { + u8 opcode; + u8 sol_not; + u8 reserved1[2]; + __be32 req_lim_delta; + u64 tag; + u8 reserved2[2]; + u8 flags; + u8 status; + __be32 data_out_res_cnt; + __be32 data_in_res_cnt; + __be32 sense_data_len; + __be32 resp_data_len; + u8 data[0]; +} __attribute__((packed)); + +#endif /* SCSI_SRP_H */ diff --git a/libdde_linux26/contrib/include/scsi/fc_encode.h b/libdde_linux26/contrib/include/scsi/fc_encode.h new file mode 100644 index 00000000..6300f556 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/fc_encode.h @@ -0,0 +1,309 @@ +/* + * Copyright(c) 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_ENCODE_H_ +#define _FC_ENCODE_H_ +#include <asm/unaligned.h> + +struct fc_ns_rft { + struct fc_ns_fid fid; /* port ID object */ + struct fc_ns_fts fts; /* FC4-types object */ +}; + +struct fc_ct_req { + struct fc_ct_hdr hdr; + union { + struct fc_ns_gid_ft gid; + struct fc_ns_rn_id rn; + struct fc_ns_rft rft; + } payload; +}; + +/** + * fill FC header fields in specified fc_frame + */ +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, + u32 did, u32 sid, enum fc_fh_type type, + u32 f_ctl, u32 parm_offset) +{ + struct fc_frame_header *fh; + + fh = fc_frame_header_get(fp); + WARN_ON(r_ctl == 0); + fh->fh_r_ctl = r_ctl; + hton24(fh->fh_d_id, did); + hton24(fh->fh_s_id, sid); + fh->fh_type = type; + hton24(fh->fh_f_ctl, f_ctl); + fh->fh_cs_ctl = 0; + fh->fh_df_ctl = 0; + fh->fh_parm_offset = htonl(parm_offset); +} + +/** + * fc_ct_hdr_fill- fills ct header and reset ct payload + * returns pointer to ct request. + */ +static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, + unsigned int op, size_t req_size) +{ + struct fc_ct_req *ct; + size_t ct_plen; + + ct_plen = sizeof(struct fc_ct_hdr) + req_size; + ct = fc_frame_payload_get(fp, ct_plen); + memset(ct, 0, ct_plen); + ct->hdr.ct_rev = FC_CT_REV; + ct->hdr.ct_fs_type = FC_FST_DIR; + ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; + ct->hdr.ct_cmd = htons((u16) op); + return ct; +} + +/** + * fc_ct_fill - Fill in a name service request frame + */ +static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op, enum fc_rctl *r_ctl, u32 *did, + enum fc_fh_type *fh_type) +{ + struct fc_ct_req *ct; + + switch (op) { + case FC_NS_GPN_FT: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; + break; + + case FC_NS_RFT_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); + hton24(ct->payload.rft.fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + break; + + case FC_NS_RPN_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); + hton24(ct->payload.rn.fr_fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + *r_ctl = FC_RCTL_DD_UNSOL_CTL; + *did = FC_FID_DIR_SERV; + *fh_type = FC_TYPE_CT; + return 0; +} + +/** + * fc_plogi_fill - Fill in plogi request frame + */ +static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op) +{ + struct fc_els_flogi *plogi; + struct fc_els_csp *csp; + struct fc_els_cssp *cp; + + plogi = fc_frame_payload_get(fp, sizeof(*plogi)); + memset(plogi, 0, sizeof(*plogi)); + plogi->fl_cmd = (u8) op; + put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); + + csp = &plogi->fl_csp; + csp->sp_hi_ver = 0x20; + csp->sp_lo_ver = 0x20; + csp->sp_bb_cred = htons(10); /* this gets set by gateway */ + csp->sp_bb_data = htons((u16) lport->mfs); + cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); + csp->sp_features = htons(FC_SP_FT_CIRO); + csp->sp_tot_seq = htons(255); /* seq. we accept */ + csp->sp_rel_off = htons(0x1f); + csp->sp_e_d_tov = htonl(lport->e_d_tov); + + cp->cp_rdfs = htons((u16) lport->mfs); + cp->cp_con_seq = htons(255); + cp->cp_open_seq = 1; +} + +/** + * fc_flogi_fill - Fill in a flogi request frame. + */ +static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_csp *sp; + struct fc_els_cssp *cp; + struct fc_els_flogi *flogi; + + flogi = fc_frame_payload_get(fp, sizeof(*flogi)); + memset(flogi, 0, sizeof(*flogi)); + flogi->fl_cmd = (u8) ELS_FLOGI; + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); + sp = &flogi->fl_csp; + sp->sp_hi_ver = 0x20; + sp->sp_lo_ver = 0x20; + sp->sp_bb_cred = htons(10); /* this gets set by gateway */ + sp->sp_bb_data = htons((u16) lport->mfs); + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); +} + +/** + * fc_logo_fill - Fill in a logo request frame. + */ +static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_logo *logo; + + logo = fc_frame_payload_get(fp, sizeof(*logo)); + memset(logo, 0, sizeof(*logo)); + logo->fl_cmd = ELS_LOGO; + hton24(logo->fl_n_port_id, fc_host_port_id(lport->host)); + logo->fl_n_port_wwn = htonll(lport->wwpn); +} + +/** + * fc_rtv_fill - Fill in RTV (read timeout value) request frame. + */ +static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rtv *rtv; + + rtv = fc_frame_payload_get(fp, sizeof(*rtv)); + memset(rtv, 0, sizeof(*rtv)); + rtv->rtv_cmd = ELS_RTV; +} + +/** + * fc_rec_fill - Fill in rec request frame + */ +static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rec *rec; + struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); + + rec = fc_frame_payload_get(fp, sizeof(*rec)); + memset(rec, 0, sizeof(*rec)); + rec->rec_cmd = ELS_REC; + hton24(rec->rec_s_id, fc_host_port_id(lport->host)); + rec->rec_ox_id = htons(ep->oxid); + rec->rec_rx_id = htons(ep->rxid); +} + +/** + * fc_prli_fill - Fill in prli request frame + */ +static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct { + struct fc_els_prli prli; + struct fc_els_spp spp; + } *pp; + + pp = fc_frame_payload_get(fp, sizeof(*pp)); + memset(pp, 0, sizeof(*pp)); + pp->prli.prli_cmd = ELS_PRLI; + pp->prli.prli_spp_len = sizeof(struct fc_els_spp); + pp->prli.prli_len = htons(sizeof(*pp)); + pp->spp.spp_type = FC_TYPE_FCP; + pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; + pp->spp.spp_params = htonl(lport->service_params); +} + +/** + * fc_scr_fill - Fill in a scr request frame. + */ +static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_scr *scr; + + scr = fc_frame_payload_get(fp, sizeof(*scr)); + memset(scr, 0, sizeof(*scr)); + scr->scr_cmd = ELS_SCR; + scr->scr_reg_func = ELS_SCRF_FULL; +} + +/** + * fc_els_fill - Fill in an ELS request frame + */ +static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport, + struct fc_frame *fp, unsigned int op, + enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type) +{ + switch (op) { + case ELS_PLOGI: + fc_plogi_fill(lport, fp, ELS_PLOGI); + *did = rport->port_id; + break; + + case ELS_FLOGI: + fc_flogi_fill(lport, fp); + *did = FC_FID_FLOGI; + break; + + case ELS_LOGO: + fc_logo_fill(lport, fp); + *did = FC_FID_FLOGI; + /* + * if rport is valid then it + * is port logo, therefore + * set did to rport id. + */ + if (rport) + *did = rport->port_id; + break; + + case ELS_RTV: + fc_rtv_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_REC: + fc_rec_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_PRLI: + fc_prli_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_SCR: + fc_scr_fill(lport, fp); + *did = FC_FID_FCTRL; + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + + *r_ctl = FC_RCTL_ELS_REQ; + *fh_type = FC_TYPE_ELS; + return 0; +} +#endif /* _FC_ENCODE_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/fc_frame.h b/libdde_linux26/contrib/include/scsi/fc_frame.h new file mode 100644 index 00000000..04d34a71 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/fc_frame.h @@ -0,0 +1,242 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FRAME_H_ +#define _FC_FRAME_H_ + +#include <linux/scatterlist.h> +#include <linux/skbuff.h> +#include <scsi/scsi_cmnd.h> + +#include <scsi/fc/fc_fs.h> +#include <scsi/fc/fc_fcp.h> +#include <scsi/fc/fc_encaps.h> + +/* + * The fc_frame interface is used to pass frame data between functions. + * The frame includes the data buffer, length, and SOF / EOF delimiter types. + * A pointer to the port structure of the receiving port is also includeded. + */ + +#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */ +#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */ + +/* + * Information about an individual fibre channel frame received or to be sent. + * The buffer may be in up to 4 additional non-contiguous sections, + * but the linear section must hold the frame header. + */ +#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */ + +#define fp_skb(fp) (&((fp)->skb)) +#define fr_hdr(fp) ((fp)->skb.data) +#define fr_len(fp) ((fp)->skb.len) +#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0])) +#define fr_dev(fp) (fr_cb(fp)->fr_dev) +#define fr_seq(fp) (fr_cb(fp)->fr_seq) +#define fr_sof(fp) (fr_cb(fp)->fr_sof) +#define fr_eof(fp) (fr_cb(fp)->fr_eof) +#define fr_flags(fp) (fr_cb(fp)->fr_flags) +#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) +#define fr_cmd(fp) (fr_cb(fp)->fr_cmd) +#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction) +#define fr_crc(fp) (fr_cb(fp)->fr_crc) + +struct fc_frame { + struct sk_buff skb; +}; + +struct fcoe_rcv_info { + struct packet_type *ptype; + struct fc_lport *fr_dev; /* transport layer private pointer */ + struct fc_seq *fr_seq; /* for use with exchange manager */ + struct scsi_cmnd *fr_cmd; /* for use of scsi command */ + u32 fr_crc; + u16 fr_max_payload; /* max FC payload */ + enum fc_sof fr_sof; /* start of frame delimiter */ + enum fc_eof fr_eof; /* end of frame delimiter */ + u8 fr_flags; /* flags - see below */ +}; + + +/* + * Get fc_frame pointer for an skb that's already been imported. + */ +static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb)); + return (struct fcoe_rcv_info *) skb->cb; +} + +/* + * fr_flags. + */ +#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */ + +/* + * Initialize a frame. + * We don't do a complete memset here for performance reasons. + * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually. + */ +static inline void fc_frame_init(struct fc_frame *fp) +{ + fr_dev(fp) = NULL; + fr_seq(fp) = NULL; + fr_flags(fp) = 0; +} + +struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len); + +struct fc_frame *__fc_frame_alloc(size_t payload_len); + +/* + * Get frame for sending via port. + */ +static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev, + size_t payload_len) +{ + return __fc_frame_alloc(payload_len); +} + +/* + * Allocate fc_frame structure and buffer. Set the initial length to + * payload_size + sizeof (struct fc_frame_header). + */ +static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len) +{ + struct fc_frame *fp; + + /* + * Note: Since len will often be a constant multiple of 4, + * this check will usually be evaluated and eliminated at compile time. + */ + if ((len % 4) != 0) + fp = fc_frame_alloc_fill(dev, len); + else + fp = _fc_frame_alloc(dev, len); + return fp; +} + +/* + * Free the fc_frame structure and buffer. + */ +static inline void fc_frame_free(struct fc_frame *fp) +{ + kfree_skb(fp_skb(fp)); +} + +static inline int fc_frame_is_linear(struct fc_frame *fp) +{ + return !skb_is_nonlinear(fp_skb(fp)); +} + +/* + * Get frame header from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + */ +static inline +struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp) +{ + WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header)); + return (struct fc_frame_header *) fr_hdr(fp); +} + +/* + * Get frame payload from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + * The len parameter is the minimum length for the payload portion. + * Returns NULL if the frame is too short. + * + * This assumes the interesting part of the payload is in the first part + * of the buffer for received data. This may not be appropriate to use for + * buffers being transmitted. + */ +static inline void *fc_frame_payload_get(const struct fc_frame *fp, + size_t len) +{ + void *pp = NULL; + + if (fr_len(fp) >= sizeof(struct fc_frame_header) + len) + pp = fc_frame_header_get(fp) + 1; + return pp; +} + +/* + * Get frame payload opcode (first byte) from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. Return 0 + * if the frame has no payload. + */ +static inline u8 fc_frame_payload_op(const struct fc_frame *fp) +{ + u8 *cp; + + cp = fc_frame_payload_get(fp, sizeof(u8)); + if (!cp) + return 0; + return *cp; + +} + +/* + * Get FC class from frame. + */ +static inline enum fc_class fc_frame_class(const struct fc_frame *fp) +{ + return fc_sof_class(fr_sof(fp)); +} + +/* + * Check the CRC in a frame. + * The CRC immediately follows the last data item *AFTER* the length. + * The return value is zero if the CRC matches. + */ +u32 fc_frame_crc_check(struct fc_frame *); + +static inline u8 fc_frame_rctl(const struct fc_frame *fp) +{ + return fc_frame_header_get(fp)->fh_r_ctl; +} + +static inline bool fc_frame_is_cmd(const struct fc_frame *fp) +{ + return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool fc_frame_is_read(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_FROM_DEVICE; + return false; +} + +static inline bool fc_frame_is_write(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_TO_DEVICE; + return false; +} + +/* + * Check for leaks. + * Print the frame header of any currently allocated frame, assuming there + * should be none at this point. + */ +void fc_frame_leak_check(void); + +#endif /* _FC_FRAME_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/fc_transport_fcoe.h b/libdde_linux26/contrib/include/scsi/fc_transport_fcoe.h new file mode 100644 index 00000000..8dca2af1 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/fc_transport_fcoe.h @@ -0,0 +1,54 @@ +#ifndef FC_TRANSPORT_FCOE_H +#define FC_TRANSPORT_FCOE_H + +#include <linux/device.h> +#include <linux/netdevice.h> +#include <scsi/scsi_host.h> +#include <scsi/libfc.h> + +/** + * struct fcoe_transport - FCoE transport struct for generic transport + * for Ethernet devices as well as pure HBAs + * + * @name: name for thsi transport + * @bus: physical bus type (pci_bus_type) + * @driver: physical bus driver for network device + * @create: entry create function + * @destroy: exit destroy function + * @list: list of transports + */ +struct fcoe_transport { + char *name; + unsigned short vendor; + unsigned short device; + struct bus_type *bus; + struct device_driver *driver; + int (*create)(struct net_device *device); + int (*destroy)(struct net_device *device); + bool (*match)(struct net_device *device); + struct list_head list; + struct list_head devlist; + struct mutex devlock; +}; + +/** + * MODULE_ALIAS_FCOE_PCI + * + * some care must be taken with this, vendor and device MUST be a hex value + * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB) + */ +#define MODULE_ALIAS_FCOE_PCI(vendor, device) \ + MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device)) + +/* exported funcs */ +int fcoe_transport_attach(struct net_device *netdev); +int fcoe_transport_release(struct net_device *netdev); +int fcoe_transport_register(struct fcoe_transport *t); +int fcoe_transport_unregister(struct fcoe_transport *t); +int fcoe_load_transport_driver(struct net_device *netdev); +int __init fcoe_transport_init(void); +int __exit fcoe_transport_exit(void); + +/* fcow_sw is the default transport */ +extern struct fcoe_transport fcoe_sw_transport; +#endif /* FC_TRANSPORT_FCOE_H */ diff --git a/libdde_linux26/contrib/include/scsi/iscsi_if.h b/libdde_linux26/contrib/include/scsi/iscsi_if.h new file mode 100644 index 00000000..d0ed5226 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/iscsi_if.h @@ -0,0 +1,401 @@ +/* + * iSCSI User/Kernel Shares (Defines, Constants, Protocol definitions, etc) + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_IF_H +#define ISCSI_IF_H + +#include <scsi/iscsi_proto.h> + +#define UEVENT_BASE 10 +#define KEVENT_BASE 100 +#define ISCSI_ERR_BASE 1000 + +enum iscsi_uevent_e { + ISCSI_UEVENT_UNKNOWN = 0, + + /* down events */ + ISCSI_UEVENT_CREATE_SESSION = UEVENT_BASE + 1, + ISCSI_UEVENT_DESTROY_SESSION = UEVENT_BASE + 2, + ISCSI_UEVENT_CREATE_CONN = UEVENT_BASE + 3, + ISCSI_UEVENT_DESTROY_CONN = UEVENT_BASE + 4, + ISCSI_UEVENT_BIND_CONN = UEVENT_BASE + 5, + ISCSI_UEVENT_SET_PARAM = UEVENT_BASE + 6, + ISCSI_UEVENT_START_CONN = UEVENT_BASE + 7, + ISCSI_UEVENT_STOP_CONN = UEVENT_BASE + 8, + ISCSI_UEVENT_SEND_PDU = UEVENT_BASE + 9, + ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10, + ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11, + + ISCSI_UEVENT_TRANSPORT_EP_CONNECT = UEVENT_BASE + 12, + ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, + ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, + + ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, + ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16, + ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17, + ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, + + /* up events */ + ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, + ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, + ISCSI_KEVENT_IF_ERROR = KEVENT_BASE + 3, + ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, + ISCSI_KEVENT_UNBIND_SESSION = KEVENT_BASE + 5, + ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6, +}; + +enum iscsi_tgt_dscvr { + ISCSI_TGT_DSCVR_SEND_TARGETS = 1, + ISCSI_TGT_DSCVR_ISNS = 2, + ISCSI_TGT_DSCVR_SLP = 3, +}; + +struct iscsi_uevent { + uint32_t type; /* k/u events type */ + uint32_t iferror; /* carries interface or resource errors */ + uint64_t transport_handle; + + union { + /* messages u -> k */ + struct msg_create_session { + uint32_t initial_cmdsn; + uint16_t cmds_max; + uint16_t queue_depth; + } c_session; + struct msg_create_bound_session { + uint64_t ep_handle; + uint32_t initial_cmdsn; + uint16_t cmds_max; + uint16_t queue_depth; + } c_bound_session; + struct msg_destroy_session { + uint32_t sid; + } d_session; + struct msg_create_conn { + uint32_t sid; + uint32_t cid; + } c_conn; + struct msg_bind_conn { + uint32_t sid; + uint32_t cid; + uint64_t transport_eph; + uint32_t is_leading; + } b_conn; + struct msg_destroy_conn { + uint32_t sid; + uint32_t cid; + } d_conn; + struct msg_send_pdu { + uint32_t sid; + uint32_t cid; + uint32_t hdr_size; + uint32_t data_size; + } send_pdu; + struct msg_set_param { + uint32_t sid; + uint32_t cid; + uint32_t param; /* enum iscsi_param */ + uint32_t len; + } set_param; + struct msg_start_conn { + uint32_t sid; + uint32_t cid; + } start_conn; + struct msg_stop_conn { + uint32_t sid; + uint32_t cid; + uint64_t conn_handle; + uint32_t flag; + } stop_conn; + struct msg_get_stats { + uint32_t sid; + uint32_t cid; + } get_stats; + struct msg_transport_connect { + uint32_t non_blocking; + } ep_connect; + struct msg_transport_poll { + uint64_t ep_handle; + uint32_t timeout_ms; + } ep_poll; + struct msg_transport_disconnect { + uint64_t ep_handle; + } ep_disconnect; + struct msg_tgt_dscvr { + enum iscsi_tgt_dscvr type; + uint32_t host_no; + /* + * enable = 1 to establish a new connection + * with the server. enable = 0 to disconnect + * from the server. Used primarily to switch + * from one iSNS server to another. + */ + uint32_t enable; + } tgt_dscvr; + struct msg_set_host_param { + uint32_t host_no; + uint32_t param; /* enum iscsi_host_param */ + uint32_t len; + } set_host_param; + } u; + union { + /* messages k -> u */ + int retcode; + struct msg_create_session_ret { + uint32_t sid; + uint32_t host_no; + } c_session_ret; + struct msg_create_conn_ret { + uint32_t sid; + uint32_t cid; + } c_conn_ret; + struct msg_unbind_session { + uint32_t sid; + uint32_t host_no; + } unbind_session; + struct msg_recv_req { + uint32_t sid; + uint32_t cid; + uint64_t recv_handle; + } recv_req; + struct msg_conn_error { + uint32_t sid; + uint32_t cid; + uint32_t error; /* enum iscsi_err */ + } connerror; + struct msg_session_destroyed { + uint32_t host_no; + uint32_t sid; + } d_session; + struct msg_transport_connect_ret { + uint64_t handle; + } ep_connect_ret; + } r; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +/* + * Common error codes + */ +enum iscsi_err { + ISCSI_OK = 0, + + ISCSI_ERR_DATASN = ISCSI_ERR_BASE + 1, + ISCSI_ERR_DATA_OFFSET = ISCSI_ERR_BASE + 2, + ISCSI_ERR_MAX_CMDSN = ISCSI_ERR_BASE + 3, + ISCSI_ERR_EXP_CMDSN = ISCSI_ERR_BASE + 4, + ISCSI_ERR_BAD_OPCODE = ISCSI_ERR_BASE + 5, + ISCSI_ERR_DATALEN = ISCSI_ERR_BASE + 6, + ISCSI_ERR_AHSLEN = ISCSI_ERR_BASE + 7, + ISCSI_ERR_PROTO = ISCSI_ERR_BASE + 8, + ISCSI_ERR_LUN = ISCSI_ERR_BASE + 9, + ISCSI_ERR_BAD_ITT = ISCSI_ERR_BASE + 10, + ISCSI_ERR_CONN_FAILED = ISCSI_ERR_BASE + 11, + ISCSI_ERR_R2TSN = ISCSI_ERR_BASE + 12, + ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13, + ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14, + ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, + ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16, + ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17, + ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18, + ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19, +}; + +/* + * iSCSI Parameters (RFC3720) + */ +enum iscsi_param { + /* passed in using netlink set param */ + ISCSI_PARAM_MAX_RECV_DLENGTH, + ISCSI_PARAM_MAX_XMIT_DLENGTH, + ISCSI_PARAM_HDRDGST_EN, + ISCSI_PARAM_DATADGST_EN, + ISCSI_PARAM_INITIAL_R2T_EN, + ISCSI_PARAM_MAX_R2T, + ISCSI_PARAM_IMM_DATA_EN, + ISCSI_PARAM_FIRST_BURST, + ISCSI_PARAM_MAX_BURST, + ISCSI_PARAM_PDU_INORDER_EN, + ISCSI_PARAM_DATASEQ_INORDER_EN, + ISCSI_PARAM_ERL, + ISCSI_PARAM_IFMARKER_EN, + ISCSI_PARAM_OFMARKER_EN, + ISCSI_PARAM_EXP_STATSN, + ISCSI_PARAM_TARGET_NAME, + ISCSI_PARAM_TPGT, + ISCSI_PARAM_PERSISTENT_ADDRESS, + ISCSI_PARAM_PERSISTENT_PORT, + ISCSI_PARAM_SESS_RECOVERY_TMO, + + /* pased in through bind conn using transport_fd */ + ISCSI_PARAM_CONN_PORT, + ISCSI_PARAM_CONN_ADDRESS, + + ISCSI_PARAM_USERNAME, + ISCSI_PARAM_USERNAME_IN, + ISCSI_PARAM_PASSWORD, + ISCSI_PARAM_PASSWORD_IN, + + ISCSI_PARAM_FAST_ABORT, + ISCSI_PARAM_ABORT_TMO, + ISCSI_PARAM_LU_RESET_TMO, + ISCSI_PARAM_HOST_RESET_TMO, + + ISCSI_PARAM_PING_TMO, + ISCSI_PARAM_RECV_TMO, + + ISCSI_PARAM_IFACE_NAME, + ISCSI_PARAM_ISID, + ISCSI_PARAM_INITIATOR_NAME, + /* must always be last */ + ISCSI_PARAM_MAX, +}; + +#define ISCSI_MAX_RECV_DLENGTH (1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH) +#define ISCSI_MAX_XMIT_DLENGTH (1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH) +#define ISCSI_HDRDGST_EN (1ULL << ISCSI_PARAM_HDRDGST_EN) +#define ISCSI_DATADGST_EN (1ULL << ISCSI_PARAM_DATADGST_EN) +#define ISCSI_INITIAL_R2T_EN (1ULL << ISCSI_PARAM_INITIAL_R2T_EN) +#define ISCSI_MAX_R2T (1ULL << ISCSI_PARAM_MAX_R2T) +#define ISCSI_IMM_DATA_EN (1ULL << ISCSI_PARAM_IMM_DATA_EN) +#define ISCSI_FIRST_BURST (1ULL << ISCSI_PARAM_FIRST_BURST) +#define ISCSI_MAX_BURST (1ULL << ISCSI_PARAM_MAX_BURST) +#define ISCSI_PDU_INORDER_EN (1ULL << ISCSI_PARAM_PDU_INORDER_EN) +#define ISCSI_DATASEQ_INORDER_EN (1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN) +#define ISCSI_ERL (1ULL << ISCSI_PARAM_ERL) +#define ISCSI_IFMARKER_EN (1ULL << ISCSI_PARAM_IFMARKER_EN) +#define ISCSI_OFMARKER_EN (1ULL << ISCSI_PARAM_OFMARKER_EN) +#define ISCSI_EXP_STATSN (1ULL << ISCSI_PARAM_EXP_STATSN) +#define ISCSI_TARGET_NAME (1ULL << ISCSI_PARAM_TARGET_NAME) +#define ISCSI_TPGT (1ULL << ISCSI_PARAM_TPGT) +#define ISCSI_PERSISTENT_ADDRESS (1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS) +#define ISCSI_PERSISTENT_PORT (1ULL << ISCSI_PARAM_PERSISTENT_PORT) +#define ISCSI_SESS_RECOVERY_TMO (1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO) +#define ISCSI_CONN_PORT (1ULL << ISCSI_PARAM_CONN_PORT) +#define ISCSI_CONN_ADDRESS (1ULL << ISCSI_PARAM_CONN_ADDRESS) +#define ISCSI_USERNAME (1ULL << ISCSI_PARAM_USERNAME) +#define ISCSI_USERNAME_IN (1ULL << ISCSI_PARAM_USERNAME_IN) +#define ISCSI_PASSWORD (1ULL << ISCSI_PARAM_PASSWORD) +#define ISCSI_PASSWORD_IN (1ULL << ISCSI_PARAM_PASSWORD_IN) +#define ISCSI_FAST_ABORT (1ULL << ISCSI_PARAM_FAST_ABORT) +#define ISCSI_ABORT_TMO (1ULL << ISCSI_PARAM_ABORT_TMO) +#define ISCSI_LU_RESET_TMO (1ULL << ISCSI_PARAM_LU_RESET_TMO) +#define ISCSI_HOST_RESET_TMO (1ULL << ISCSI_PARAM_HOST_RESET_TMO) +#define ISCSI_PING_TMO (1ULL << ISCSI_PARAM_PING_TMO) +#define ISCSI_RECV_TMO (1ULL << ISCSI_PARAM_RECV_TMO) +#define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME) +#define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) +#define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) + +/* iSCSI HBA params */ +enum iscsi_host_param { + ISCSI_HOST_PARAM_HWADDRESS, + ISCSI_HOST_PARAM_INITIATOR_NAME, + ISCSI_HOST_PARAM_NETDEV_NAME, + ISCSI_HOST_PARAM_IPADDRESS, + ISCSI_HOST_PARAM_MAX, +}; + +#define ISCSI_HOST_HWADDRESS (1ULL << ISCSI_HOST_PARAM_HWADDRESS) +#define ISCSI_HOST_INITIATOR_NAME (1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME) +#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) +#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS) + +#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) +#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) + +/* + * These flags presents iSCSI Data-Path capabilities. + */ +#define CAP_RECOVERY_L0 0x1 +#define CAP_RECOVERY_L1 0x2 +#define CAP_RECOVERY_L2 0x4 +#define CAP_MULTI_R2T 0x8 +#define CAP_HDRDGST 0x10 +#define CAP_DATADGST 0x20 +#define CAP_MULTI_CONN 0x40 +#define CAP_TEXT_NEGO 0x80 +#define CAP_MARKERS 0x100 +#define CAP_FW_DB 0x200 +#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ +#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */ +#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ +#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal, + and verification */ + +/* + * These flags describes reason of stop_conn() call + */ +#define STOP_CONN_TERM 0x1 +#define STOP_CONN_SUSPEND 0x2 +#define STOP_CONN_RECOVER 0x3 + +#define ISCSI_STATS_CUSTOM_MAX 32 +#define ISCSI_STATS_CUSTOM_DESC_MAX 64 +struct iscsi_stats_custom { + char desc[ISCSI_STATS_CUSTOM_DESC_MAX]; + uint64_t value; +}; + +/* + * struct iscsi_stats - iSCSI Statistics (iSCSI MIB) + * + * Note: this structure contains counters collected on per-connection basis. + */ +struct iscsi_stats { + /* octets */ + uint64_t txdata_octets; + uint64_t rxdata_octets; + + /* xmit pdus */ + uint32_t noptx_pdus; + uint32_t scsicmd_pdus; + uint32_t tmfcmd_pdus; + uint32_t login_pdus; + uint32_t text_pdus; + uint32_t dataout_pdus; + uint32_t logout_pdus; + uint32_t snack_pdus; + + /* recv pdus */ + uint32_t noprx_pdus; + uint32_t scsirsp_pdus; + uint32_t tmfrsp_pdus; + uint32_t textrsp_pdus; + uint32_t datain_pdus; + uint32_t logoutrsp_pdus; + uint32_t r2t_pdus; + uint32_t async_pdus; + uint32_t rjt_pdus; + + /* errors */ + uint32_t digest_err; + uint32_t timeout_err; + + /* + * iSCSI Custom Statistics support, i.e. Transport could + * extend existing MIB statistics with its own specific statistics + * up to ISCSI_STATS_CUSTOM_MAX + */ + uint32_t custom_length; + struct iscsi_stats_custom custom[0] + __attribute__ ((aligned (sizeof(uint64_t)))); +}; + +#endif diff --git a/libdde_linux26/contrib/include/scsi/iscsi_proto.h b/libdde_linux26/contrib/include/scsi/iscsi_proto.h new file mode 100644 index 00000000..f2a2c116 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/iscsi_proto.h @@ -0,0 +1,620 @@ +/* + * RFC 3720 (iSCSI) protocol data types + * + * Copyright (C) 2005 Dmitry Yusupov + * Copyright (C) 2005 Alex Aizman + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef ISCSI_PROTO_H +#define ISCSI_PROTO_H + +#include <linux/types.h> +#include <scsi/scsi.h> + +#define ISCSI_DRAFT20_VERSION 0x00 + +/* default iSCSI listen port for incoming connections */ +#define ISCSI_LISTEN_PORT 3260 + +/* Padding word length */ +#define ISCSI_PAD_LEN 4 + +/* + * useful common(control and data pathes) macro + */ +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) +#define hton24(p, v) { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ +} +#define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;} + +/* initiator tags; opaque for target */ +typedef uint32_t __bitwise__ itt_t; +/* below makes sense only for initiator that created this tag */ +#define build_itt(itt, age) ((__force itt_t)\ + ((itt) | ((age) << ISCSI_AGE_SHIFT))) +#define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK) +#define RESERVED_ITT ((__force itt_t)0xffffffff) + +/* + * iSCSI Template Message Header + */ +struct iscsi_hdr { + uint8_t opcode; + uint8_t flags; /* Final bit */ + uint8_t rsvd2[2]; + uint8_t hlength; /* AHSs total length */ + uint8_t dlength[3]; /* Data length */ + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag, opaque for target */ + __be32 ttt; /* Target Task Tag */ + __be32 statsn; + __be32 exp_statsn; + __be32 max_statsn; + uint8_t other[12]; +}; + +/************************* RFC 3720 Begin *****************************/ + +#define ISCSI_RESERVED_TAG 0xffffffff + +/* Opcode encoding bits */ +#define ISCSI_OP_RETRY 0x80 +#define ISCSI_OP_IMMEDIATE 0x40 +#define ISCSI_OPCODE_MASK 0x3F + +/* Initiator Opcode values */ +#define ISCSI_OP_NOOP_OUT 0x00 +#define ISCSI_OP_SCSI_CMD 0x01 +#define ISCSI_OP_SCSI_TMFUNC 0x02 +#define ISCSI_OP_LOGIN 0x03 +#define ISCSI_OP_TEXT 0x04 +#define ISCSI_OP_SCSI_DATA_OUT 0x05 +#define ISCSI_OP_LOGOUT 0x06 +#define ISCSI_OP_SNACK 0x10 + +#define ISCSI_OP_VENDOR1_CMD 0x1c +#define ISCSI_OP_VENDOR2_CMD 0x1d +#define ISCSI_OP_VENDOR3_CMD 0x1e +#define ISCSI_OP_VENDOR4_CMD 0x1f + +/* Target Opcode values */ +#define ISCSI_OP_NOOP_IN 0x20 +#define ISCSI_OP_SCSI_CMD_RSP 0x21 +#define ISCSI_OP_SCSI_TMFUNC_RSP 0x22 +#define ISCSI_OP_LOGIN_RSP 0x23 +#define ISCSI_OP_TEXT_RSP 0x24 +#define ISCSI_OP_SCSI_DATA_IN 0x25 +#define ISCSI_OP_LOGOUT_RSP 0x26 +#define ISCSI_OP_R2T 0x31 +#define ISCSI_OP_ASYNC_EVENT 0x32 +#define ISCSI_OP_REJECT 0x3f + +struct iscsi_ahs_hdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t ahspec[5]; +}; + +#define ISCSI_AHSTYPE_CDB 1 +#define ISCSI_AHSTYPE_RLENGTH 2 +#define ISCSI_CDB_SIZE 16 + +/* iSCSI PDU Header */ +struct iscsi_cmd { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 data_length; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t cdb[ISCSI_CDB_SIZE]; /* SCSI Command Block */ + /* Additional Data (Command Dependent) */ +}; + +/* Command PDU flags */ +#define ISCSI_FLAG_CMD_FINAL 0x80 +#define ISCSI_FLAG_CMD_READ 0x40 +#define ISCSI_FLAG_CMD_WRITE 0x20 +#define ISCSI_FLAG_CMD_ATTR_MASK 0x07 /* 3 bits */ + +/* SCSI Command Attribute values */ +#define ISCSI_ATTR_UNTAGGED 0 +#define ISCSI_ATTR_SIMPLE 1 +#define ISCSI_ATTR_ORDERED 2 +#define ISCSI_ATTR_HEAD_OF_QUEUE 3 +#define ISCSI_ATTR_ACA 4 + +struct iscsi_rlength_ahdr { + __be16 ahslength; + uint8_t ahstype; + uint8_t reserved; + __be32 read_length; +}; + +/* Extended CDB AHS */ +struct iscsi_ecdb_ahdr { + __be16 ahslength; /* CDB length - 15, including reserved byte */ + uint8_t ahstype; + uint8_t reserved; + /* 4-byte aligned extended CDB spillover */ + uint8_t ecdb[SCSI_MAX_VARLEN_CDB_SIZE - ISCSI_CDB_SIZE]; +}; + +/* SCSI Response Header */ +struct iscsi_cmd_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd1; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 exp_datasn; + __be32 bi_residual_count; + __be32 residual_count; + /* Response or Sense Data (optional) */ +}; + +/* Command Response PDU flags */ +#define ISCSI_FLAG_CMD_BIDI_OVERFLOW 0x10 +#define ISCSI_FLAG_CMD_BIDI_UNDERFLOW 0x08 +#define ISCSI_FLAG_CMD_OVERFLOW 0x04 +#define ISCSI_FLAG_CMD_UNDERFLOW 0x02 + +/* iSCSI Status values. Valid if Rsp Selector bit is not set */ +#define ISCSI_STATUS_CMD_COMPLETED 0 +#define ISCSI_STATUS_TARGET_FAILURE 1 +#define ISCSI_STATUS_SUBSYS_FAILURE 2 + +/* Asynchronous Event Header */ +struct iscsi_async { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + uint8_t rsvd4[8]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t async_event; + uint8_t async_vcode; + __be16 param1; + __be16 param2; + __be16 param3; + uint8_t rsvd5[4]; +}; + +/* iSCSI Event Codes */ +#define ISCSI_ASYNC_MSG_SCSI_EVENT 0 +#define ISCSI_ASYNC_MSG_REQUEST_LOGOUT 1 +#define ISCSI_ASYNC_MSG_DROPPING_CONNECTION 2 +#define ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS 3 +#define ISCSI_ASYNC_MSG_PARAM_NEGOTIATION 4 +#define ISCSI_ASYNC_MSG_VENDOR_SPECIFIC 255 + +/* NOP-Out Message */ +struct iscsi_nopout { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* NOP-In Message */ +struct iscsi_nopin { + uint8_t opcode; + uint8_t flags; + __be16 rsvd2; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd4[12]; +}; + +/* SCSI Task Management Message Header */ +struct iscsi_tm { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + itt_t rtt; /* Reference Task Tag */ + __be32 cmdsn; + __be32 exp_statsn; + __be32 refcmdsn; + __be32 exp_datasn; + uint8_t rsvd2[8]; +}; + +#define ISCSI_FLAG_TM_FUNC_MASK 0x7F + +/* Function values */ +#define ISCSI_TM_FUNC_ABORT_TASK 1 +#define ISCSI_TM_FUNC_ABORT_TASK_SET 2 +#define ISCSI_TM_FUNC_CLEAR_ACA 3 +#define ISCSI_TM_FUNC_CLEAR_TASK_SET 4 +#define ISCSI_TM_FUNC_LOGICAL_UNIT_RESET 5 +#define ISCSI_TM_FUNC_TARGET_WARM_RESET 6 +#define ISCSI_TM_FUNC_TARGET_COLD_RESET 7 +#define ISCSI_TM_FUNC_TASK_REASSIGN 8 + +/* SCSI Task Management Response Header */ +struct iscsi_tm_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Response values below */ + uint8_t qualifier; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + itt_t itt; /* Initiator Task Tag */ + itt_t rtt; /* Reference Task Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd3[12]; +}; + +/* Response values */ +#define ISCSI_TMF_RSP_COMPLETE 0x00 +#define ISCSI_TMF_RSP_NO_TASK 0x01 +#define ISCSI_TMF_RSP_NO_LUN 0x02 +#define ISCSI_TMF_RSP_TASK_ALLEGIANT 0x03 +#define ISCSI_TMF_RSP_NO_FAILOVER 0x04 +#define ISCSI_TMF_RSP_NOT_SUPPORTED 0x05 +#define ISCSI_TMF_RSP_AUTH_FAILED 0x06 +#define ISCSI_TMF_RSP_REJECTED 0xff + +/* Ready To Transfer Header */ +struct iscsi_r2t_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 ttt; /* Target Transfer Tag */ + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 r2tsn; + __be32 data_offset; + __be32 data_length; +}; + +/* SCSI Data Hdr */ +struct iscsi_data { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t rsvd3; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; + __be32 ttt; + __be32 rsvd4; + __be32 exp_statsn; + __be32 rsvd5; + __be32 datasn; + __be32 offset; + __be32 rsvd6; + /* Payload */ +}; + +/* SCSI Data Response Hdr */ +struct iscsi_data_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2; + uint8_t cmd_status; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t lun[8]; + itt_t itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + __be32 offset; + __be32 residual_count; +}; + +/* Data Response PDU flags */ +#define ISCSI_FLAG_DATA_ACK 0x40 +#define ISCSI_FLAG_DATA_OVERFLOW 0x04 +#define ISCSI_FLAG_DATA_UNDERFLOW 0x02 +#define ISCSI_FLAG_DATA_STATUS 0x01 + +/* Text Header */ +struct iscsi_text { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + itt_t itt; + __be32 ttt; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; + /* Text - key=value pairs */ +}; + +#define ISCSI_FLAG_TEXT_CONTINUE 0x40 + +/* Text Response Header */ +struct iscsi_text_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd4[8]; + itt_t itt; + __be32 ttt; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t rsvd5[12]; + /* Text Response - key:value pairs */ +}; + +/* Login Header */ +struct iscsi_login { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t min_version; /* Min. version supported */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + itt_t itt; /* Initiator Task Tag */ + __be16 cid; + __be16 rsvd3; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd5[16]; +}; + +/* Login PDU flags */ +#define ISCSI_FLAG_LOGIN_TRANSIT 0x80 +#define ISCSI_FLAG_LOGIN_CONTINUE 0x40 +#define ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK 0x0C /* 2 bits */ +#define ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK 0x03 /* 2 bits */ + +#define ISCSI_LOGIN_CURRENT_STAGE(flags) \ + ((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) +#define ISCSI_LOGIN_NEXT_STAGE(flags) \ + (flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK) + +/* Login Response Header */ +struct iscsi_login_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t max_version; /* Max. version supported */ + uint8_t active_version; /* Active version */ + uint8_t hlength; + uint8_t dlength[3]; + uint8_t isid[6]; /* Initiator Session ID */ + __be16 tsih; /* Target Session Handle */ + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd3; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + uint8_t status_class; /* see Login RSP ststus classes below */ + uint8_t status_detail; /* see Login RSP Status details below */ + uint8_t rsvd4[10]; +}; + +/* Login stage (phase) codes for CSG, NSG */ +#define ISCSI_INITIAL_LOGIN_STAGE -1 +#define ISCSI_SECURITY_NEGOTIATION_STAGE 0 +#define ISCSI_OP_PARMS_NEGOTIATION_STAGE 1 +#define ISCSI_FULL_FEATURE_PHASE 3 + +/* Login Status response classes */ +#define ISCSI_STATUS_CLS_SUCCESS 0x00 +#define ISCSI_STATUS_CLS_REDIRECT 0x01 +#define ISCSI_STATUS_CLS_INITIATOR_ERR 0x02 +#define ISCSI_STATUS_CLS_TARGET_ERR 0x03 + +/* Login Status response detail codes */ +/* Class-0 (Success) */ +#define ISCSI_LOGIN_STATUS_ACCEPT 0x00 + +/* Class-1 (Redirection) */ +#define ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP 0x01 +#define ISCSI_LOGIN_STATUS_TGT_MOVED_PERM 0x02 + +/* Class-2 (Initiator Error) */ +#define ISCSI_LOGIN_STATUS_INIT_ERR 0x00 +#define ISCSI_LOGIN_STATUS_AUTH_FAILED 0x01 +#define ISCSI_LOGIN_STATUS_TGT_FORBIDDEN 0x02 +#define ISCSI_LOGIN_STATUS_TGT_NOT_FOUND 0x03 +#define ISCSI_LOGIN_STATUS_TGT_REMOVED 0x04 +#define ISCSI_LOGIN_STATUS_NO_VERSION 0x05 +#define ISCSI_LOGIN_STATUS_ISID_ERROR 0x06 +#define ISCSI_LOGIN_STATUS_MISSING_FIELDS 0x07 +#define ISCSI_LOGIN_STATUS_CONN_ADD_FAILED 0x08 +#define ISCSI_LOGIN_STATUS_NO_SESSION_TYPE 0x09 +#define ISCSI_LOGIN_STATUS_NO_SESSION 0x0a +#define ISCSI_LOGIN_STATUS_INVALID_REQUEST 0x0b + +/* Class-3 (Target Error) */ +#define ISCSI_LOGIN_STATUS_TARGET_ERROR 0x00 +#define ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE 0x01 +#define ISCSI_LOGIN_STATUS_NO_RESOURCES 0x02 + +/* Logout Header */ +struct iscsi_logout { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd1[2]; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd2[8]; + itt_t itt; /* Initiator Task Tag */ + __be16 cid; + uint8_t rsvd3[2]; + __be32 cmdsn; + __be32 exp_statsn; + uint8_t rsvd4[16]; +}; + +/* Logout PDU flags */ +#define ISCSI_FLAG_LOGOUT_REASON_MASK 0x7F + +/* logout reason_code values */ + +#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0 +#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1 +#define ISCSI_LOGOUT_REASON_RECOVERY 2 +#define ISCSI_LOGOUT_REASON_AEN_REQUEST 3 + +/* Logout Response Header */ +struct iscsi_logout_rsp { + uint8_t opcode; + uint8_t flags; + uint8_t response; /* see Logout response values below */ + uint8_t rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd3[8]; + itt_t itt; /* Initiator Task Tag */ + __be32 rsvd4; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 rsvd5; + __be16 t2wait; + __be16 t2retain; + __be32 rsvd6; +}; + +/* logout response status values */ + +#define ISCSI_LOGOUT_SUCCESS 0 +#define ISCSI_LOGOUT_CID_NOT_FOUND 1 +#define ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2 +#define ISCSI_LOGOUT_CLEANUP_FAILED 3 + +/* SNACK Header */ +struct iscsi_snack { + uint8_t opcode; + uint8_t flags; + uint8_t rsvd2[14]; + itt_t itt; + __be32 begrun; + __be32 runlength; + __be32 exp_statsn; + __be32 rsvd3; + __be32 exp_datasn; + uint8_t rsvd6[8]; +}; + +/* SNACK PDU flags */ +#define ISCSI_FLAG_SNACK_TYPE_MASK 0x0F /* 4 bits */ + +/* Reject Message Header */ +struct iscsi_reject { + uint8_t opcode; + uint8_t flags; + uint8_t reason; + uint8_t rsvd2; + uint8_t hlength; + uint8_t dlength[3]; + uint8_t rsvd3[8]; + __be32 ffffffff; + uint8_t rsvd4[4]; + __be32 statsn; + __be32 exp_cmdsn; + __be32 max_cmdsn; + __be32 datasn; + uint8_t rsvd5[8]; + /* Text - Rejected hdr */ +}; + +/* Reason for Reject */ +#define ISCSI_REASON_CMD_BEFORE_LOGIN 1 +#define ISCSI_REASON_DATA_DIGEST_ERROR 2 +#define ISCSI_REASON_DATA_SNACK_REJECT 3 +#define ISCSI_REASON_PROTOCOL_ERROR 4 +#define ISCSI_REASON_CMD_NOT_SUPPORTED 5 +#define ISCSI_REASON_IMM_CMD_REJECT 6 +#define ISCSI_REASON_TASK_IN_PROGRESS 7 +#define ISCSI_REASON_INVALID_SNACK 8 +#define ISCSI_REASON_BOOKMARK_INVALID 9 +#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10 +#define ISCSI_REASON_NEGOTIATION_RESET 11 + +/* Max. number of Key=Value pairs in a text message */ +#define MAX_KEY_VALUE_PAIRS 8192 + +/* maximum length for text keys/values */ +#define KEY_MAXLEN 64 +#define VALUE_MAXLEN 255 +#define TARGET_NAME_MAXLEN VALUE_MAXLEN + +#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192 +#define ISCSI_MIN_MAX_RECV_SEG_LEN 512 +#define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215 + +#define ISCSI_DEF_FIRST_BURST_LEN 65536 +#define ISCSI_MIN_FIRST_BURST_LEN 512 +#define ISCSI_MAX_FIRST_BURST_LEN 16777215 + +#define ISCSI_DEF_MAX_BURST_LEN 262144 +#define ISCSI_MIN_MAX_BURST_LEN 512 +#define ISCSI_MAX_MAX_BURST_LEN 16777215 + +#define ISCSI_DEF_TIME2WAIT 2 + +/************************* RFC 3720 End *****************************/ + +#endif /* ISCSI_PROTO_H */ diff --git a/libdde_linux26/contrib/include/scsi/libfc.h b/libdde_linux26/contrib/include/scsi/libfc.h new file mode 100644 index 00000000..a2e126b8 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libfc.h @@ -0,0 +1,960 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFC_H_ +#define _LIBFC_H_ + +#include <linux/timer.h> +#include <linux/if.h> + +#include <scsi/scsi_transport.h> +#include <scsi/scsi_transport_fc.h> + +#include <scsi/fc/fc_fcp.h> +#include <scsi/fc/fc_ns.h> +#include <scsi/fc/fc_els.h> +#include <scsi/fc/fc_gs.h> + +#include <scsi/fc_frame.h> + +#define LIBFC_DEBUG + +#ifdef LIBFC_DEBUG +/* Log messages */ +#define FC_DBG(fmt, args...) \ + do { \ + printk(KERN_INFO "%s " fmt, __func__, ##args); \ + } while (0) +#else +#define FC_DBG(fmt, args...) +#endif + +/* + * libfc error codes + */ +#define FC_NO_ERR 0 /* no error */ +#define FC_EX_TIMEOUT 1 /* Exchange timeout */ +#define FC_EX_CLOSED 2 /* Exchange closed */ + +/* some helpful macros */ + +#define ntohll(x) be64_to_cpu(x) +#define htonll(x) cpu_to_be64(x) + +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) + +#define hton24(p, v) do { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ + } while (0) + +/* + * FC HBA status + */ +enum fc_lport_state { + LPORT_ST_NONE = 0, + LPORT_ST_FLOGI, + LPORT_ST_DNS, + LPORT_ST_RPN_ID, + LPORT_ST_RFT_ID, + LPORT_ST_SCR, + LPORT_ST_READY, + LPORT_ST_LOGO, + LPORT_ST_RESET +}; + +enum fc_disc_event { + DISC_EV_NONE = 0, + DISC_EV_SUCCESS, + DISC_EV_FAILED +}; + +enum fc_rport_state { + RPORT_ST_NONE = 0, + RPORT_ST_INIT, /* initialized */ + RPORT_ST_PLOGI, /* waiting for PLOGI completion */ + RPORT_ST_PRLI, /* waiting for PRLI completion */ + RPORT_ST_RTV, /* waiting for RTV completion */ + RPORT_ST_READY, /* ready for use */ + RPORT_ST_LOGO, /* port logout sent */ +}; + +enum fc_rport_trans_state { + FC_PORTSTATE_ROGUE, + FC_PORTSTATE_REAL, +}; + +/** + * struct fc_disc_port - temporary discovery port to hold rport identifiers + * @lp: Fibre Channel host port instance + * @peers: node for list management during discovery and RSCN processing + * @ids: identifiers structure to pass to fc_remote_port_add() + * @rport_work: work struct for starting the rport state machine + */ +struct fc_disc_port { + struct fc_lport *lp; + struct list_head peers; + struct fc_rport_identifiers ids; + struct work_struct rport_work; +}; + +enum fc_rport_event { + RPORT_EV_NONE = 0, + RPORT_EV_CREATED, + RPORT_EV_FAILED, + RPORT_EV_STOP, + RPORT_EV_LOGO +}; + +struct fc_rport_operations { + void (*event_callback)(struct fc_lport *, struct fc_rport *, + enum fc_rport_event); +}; + +/** + * struct fc_rport_libfc_priv - libfc internal information about a remote port + * @local_port: Fibre Channel host port instance + * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges + * @flags: REC and RETRY supported flags + * @max_seq: maximum number of concurrent sequences + * @retries: retry count in current state + * @e_d_tov: error detect timeout value (in msec) + * @r_a_tov: resource allocation timeout value (in msec) + * @rp_mutex: mutex protects rport + * @retry_work: + * @event_callback: Callback for rport READY, FAILED or LOGO + */ +struct fc_rport_libfc_priv { + struct fc_lport *local_port; + enum fc_rport_state rp_state; + u16 flags; + #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) + #define FC_RP_FLAGS_RETRY (1 << 1) + u16 max_seq; + unsigned int retries; + unsigned int e_d_tov; + unsigned int r_a_tov; + enum fc_rport_trans_state trans_state; + struct mutex rp_mutex; + struct delayed_work retry_work; + enum fc_rport_event event; + struct fc_rport_operations *ops; + struct list_head peers; + struct work_struct event_work; +}; + +#define PRIV_TO_RPORT(x) \ + (struct fc_rport *)((void *)x - sizeof(struct fc_rport)); +#define RPORT_TO_PRIV(x) \ + (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport)); + +struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *); + +static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn) +{ + rport->node_name = wwnn; + rport->port_name = wwpn; +} + +/* + * fcoe stats structure + */ +struct fcoe_dev_stats { + u64 SecondsSinceLastReset; + u64 TxFrames; + u64 TxWords; + u64 RxFrames; + u64 RxWords; + u64 ErrorFrames; + u64 DumpedFrames; + u64 LinkFailureCount; + u64 LossOfSignalCount; + u64 InvalidTxWordCount; + u64 InvalidCRCCount; + u64 InputRequests; + u64 OutputRequests; + u64 ControlRequests; + u64 InputMegabytes; + u64 OutputMegabytes; +}; + +/* + * els data is used for passing ELS respone specific + * data to send ELS response mainly using infomation + * in exchange and sequence in EM layer. + */ +struct fc_seq_els_data { + struct fc_frame *fp; + enum fc_els_rjt_reason reason; + enum fc_els_rjt_explan explan; +}; + +/* + * FCP request structure, one for each scsi cmd request + */ +struct fc_fcp_pkt { + /* + * housekeeping stuff + */ + struct fc_lport *lp; /* handle to hba struct */ + u16 state; /* scsi_pkt state state */ + u16 tgt_flags; /* target flags */ + atomic_t ref_cnt; /* fcp pkt ref count */ + spinlock_t scsi_pkt_lock; /* Must be taken before the host lock + * if both are held at the same time */ + /* + * SCSI I/O related stuff + */ + struct scsi_cmnd *cmd; /* scsi command pointer. set/clear + * under host lock */ + struct list_head list; /* tracks queued commands. access under + * host lock */ + /* + * timeout related stuff + */ + struct timer_list timer; /* command timer */ + struct completion tm_done; + int wait_for_comp; + unsigned long start_time; /* start jiffie */ + unsigned long end_time; /* end jiffie */ + unsigned long last_pkt_time; /* jiffies of last frame received */ + + /* + * scsi cmd and data transfer information + */ + u32 data_len; + /* + * transport related veriables + */ + struct fcp_cmnd cdb_cmd; + size_t xfer_len; + u32 xfer_contig_end; /* offset of end of contiguous xfer */ + u16 max_payload; /* max payload size in bytes */ + + /* + * scsi/fcp return status + */ + u32 io_status; /* SCSI result upper 24 bits */ + u8 cdb_status; + u8 status_code; /* FCP I/O status */ + /* bit 3 Underrun bit 2: overrun */ + u8 scsi_comp_flags; + u32 req_flags; /* bit 0: read bit:1 write */ + u32 scsi_resid; /* residule length */ + + struct fc_rport *rport; /* remote port pointer */ + struct fc_seq *seq_ptr; /* current sequence pointer */ + /* + * Error Processing + */ + u8 recov_retry; /* count of recovery retries */ + struct fc_seq *recov_seq; /* sequence for REC or SRR */ +}; + +/* + * Structure and function definitions for managing Fibre Channel Exchanges + * and Sequences + * + * fc_exch holds state for one exchange and links to its active sequence. + * + * fc_seq holds the state for an individual sequence. + */ + +struct fc_exch_mgr; + +/* + * Sequence. + */ +struct fc_seq { + u8 id; /* seq ID */ + u16 ssb_stat; /* status flags for sequence status block */ + u16 cnt; /* frames sent so far on sequence */ + u32 rec_data; /* FC-4 value for REC */ +}; + +#define FC_EX_DONE (1 << 0) /* ep is completed */ +#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */ + +/* + * Exchange. + * + * Locking notes: The ex_lock protects following items: + * state, esb_stat, f_ctl, seq.ssb_stat + * seq_id + * sequence allocation + */ +struct fc_exch { + struct fc_exch_mgr *em; /* exchange manager */ + u32 state; /* internal driver state */ + u16 xid; /* our exchange ID */ + struct list_head ex_list; /* free or busy list linkage */ + spinlock_t ex_lock; /* lock covering exchange state */ + atomic_t ex_refcnt; /* reference counter */ + struct delayed_work timeout_work; /* timer for upper level protocols */ + struct fc_lport *lp; /* fc device instance */ + u16 oxid; /* originator's exchange ID */ + u16 rxid; /* responder's exchange ID */ + u32 oid; /* originator's FCID */ + u32 sid; /* source FCID */ + u32 did; /* destination FCID */ + u32 esb_stat; /* exchange status for ESB */ + u32 r_a_tov; /* r_a_tov from rport (msec) */ + u8 seq_id; /* next sequence ID to use */ + u32 f_ctl; /* F_CTL flags for sequences */ + u8 fh_type; /* frame type */ + enum fc_class class; /* class of service */ + struct fc_seq seq; /* single sequence */ + /* + * Handler for responses to this current exchange. + */ + void (*resp)(struct fc_seq *, struct fc_frame *, void *); + void (*destructor)(struct fc_seq *, void *); + /* + * arg is passed as void pointer to exchange + * resp and destructor handlers + */ + void *arg; +}; +#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) + +struct libfc_function_template { + + /* + * Interface to send a FC frame + * + * STATUS: REQUIRED + */ + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); + + /* + * Interface to send ELS/CT frames + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*elsct_send)(struct fc_lport *lport, + struct fc_rport *rport, + struct fc_frame *fp, + unsigned int op, + void (*resp)(struct fc_seq *, + struct fc_frame *fp, + void *arg), + void *arg, u32 timer_msec); + + /* + * Send the FC frame payload using a new exchange and sequence. + * + * The frame pointer with some of the header's fields must be + * filled before calling exch_seq_send(), those fields are, + * + * - routing control + * - FC port did + * - FC port sid + * - FC header type + * - frame control + * - parameter or relative offset + * + * The exchange response handler is set in this routine to resp() + * function pointer. It can be called in two scenarios: if a timeout + * occurs or if a response frame is received for the exchange. The + * fc_frame pointer in response handler will also indicate timeout + * as error using IS_ERR related macros. + * + * The exchange destructor handler is also set in this routine. + * The destructor handler is invoked by EM layer when exchange + * is about to free, this can be used by caller to free its + * resources along with exchange free. + * + * The arg is passed back to resp and destructor handler. + * + * The timeout value (in msec) for an exchange is set if non zero + * timer_msec argument is specified. The timer is canceled when + * it fires or when the exchange is done. The exchange timeout handler + * is registered by EM layer. + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, unsigned int timer_msec); + + /* + * Send a frame using an existing sequence and exchange. + * + * STATUS: OPTIONAL + */ + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* + * Send an ELS response using infomation from a previous + * exchange and sequence. + * + * STATUS: OPTIONAL + */ + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + + /* + * Abort an exchange and sequence. Generally called because of a + * exchange timeout or an abort from the upper layer. + * + * A timer_msec can be specified for abort timeout, if non-zero + * timer_msec value is specified then exchange resp handler + * will be called with timeout error if no response to abort. + * + * STATUS: OPTIONAL + */ + int (*seq_exch_abort)(const struct fc_seq *req_sp, + unsigned int timer_msec); + + /* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + * + * STATUS: OPTIONAL + */ + void (*exch_done)(struct fc_seq *sp); + + /* + * Assigns a EM and a free XID for an new exchange and then + * allocates a new exchange and sequence pair. + * The fp can be used to determine free XID. + * + * STATUS: OPTIONAL + */ + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); + + /* + * Release previously assigned XID by exch_get API. + * The LLD may implement this if XID is assigned by LLD + * in exch_get(). + * + * STATUS: OPTIONAL + */ + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, + u16 ex_id); + + /* + * Start a new sequence on the same exchange/sequence tuple. + * + * STATUS: OPTIONAL + */ + struct fc_seq *(*seq_start_next)(struct fc_seq *sp); + + /* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + * + * STATUS: OPTIONAL + */ + void (*exch_mgr_reset)(struct fc_lport *, + u32 s_id, u32 d_id); + + /* + * Flush the rport work queue. Generally used before shutdown. + * + * STATUS: OPTIONAL + */ + void (*rport_flush_queue)(void); + + /* + * Receive a frame for a local port. + * + * STATUS: OPTIONAL + */ + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* + * Reset the local port. + * + * STATUS: OPTIONAL + */ + int (*lport_reset)(struct fc_lport *); + + /* + * Create a remote port + */ + struct fc_rport *(*rport_create)(struct fc_disc_port *); + + /* + * Initiates the RP state machine. It is called from the LP module. + * This function will issue the following commands to the N_Port + * identified by the FC ID provided. + * + * - PLOGI + * - PRLI + * - RTV + * + * STATUS: OPTIONAL + */ + int (*rport_login)(struct fc_rport *rport); + + /* + * Logoff, and remove the rport from the transport if + * it had been added. This will send a LOGO to the target. + * + * STATUS: OPTIONAL + */ + int (*rport_logoff)(struct fc_rport *rport); + + /* + * Recieve a request from a remote port. + * + * STATUS: OPTIONAL + */ + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, + struct fc_rport *); + + /* + * lookup an rport by it's port ID. + * + * STATUS: OPTIONAL + */ + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); + + /* + * Send a fcp cmd from fsp pkt. + * Called with the SCSI host lock unlocked and irqs disabled. + * + * The resp handler is called when FCP_RSP received. + * + * STATUS: OPTIONAL + */ + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, + void (*resp)(struct fc_seq *, struct fc_frame *fp, + void *arg)); + + /* + * Cleanup the FCP layer, used durring link down and reset + * + * STATUS: OPTIONAL + */ + void (*fcp_cleanup)(struct fc_lport *lp); + + /* + * Abort all I/O on a local port + * + * STATUS: OPTIONAL + */ + void (*fcp_abort_io)(struct fc_lport *lp); + + /* + * Receive a request for the discovery layer. + * + * STATUS: OPTIONAL + */ + void (*disc_recv_req)(struct fc_seq *, + struct fc_frame *, struct fc_lport *); + + /* + * Start discovery for a local port. + * + * STATUS: OPTIONAL + */ + void (*disc_start)(void (*disc_callback)(struct fc_lport *, + enum fc_disc_event), + struct fc_lport *); + + /* + * Stop discovery for a given lport. This will remove + * all discovered rports + * + * STATUS: OPTIONAL + */ + void (*disc_stop) (struct fc_lport *); + + /* + * Stop discovery for a given lport. This will block + * until all discovered rports are deleted from the + * FC transport class + * + * STATUS: OPTIONAL + */ + void (*disc_stop_final) (struct fc_lport *); +}; + +/* information used by the discovery layer */ +struct fc_disc { + unsigned char retry_count; + unsigned char delay; + unsigned char pending; + unsigned char requested; + unsigned short seq_count; + unsigned char buf_len; + enum fc_disc_event event; + + void (*disc_callback)(struct fc_lport *, + enum fc_disc_event); + + struct list_head rports; + struct fc_lport *lport; + struct mutex disc_mutex; + struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ + struct delayed_work disc_work; +}; + +struct fc_lport { + struct list_head list; + + /* Associations */ + struct Scsi_Host *host; + struct fc_exch_mgr *emp; + struct fc_rport *dns_rp; + struct fc_rport *ptp_rp; + void *scsi_priv; + struct fc_disc disc; + + /* Operational Information */ + struct libfc_function_template tt; + u8 link_up; + u8 qfull; + enum fc_lport_state state; + unsigned long boot_time; + + struct fc_host_statistics host_stats; + struct fcoe_dev_stats *dev_stats[NR_CPUS]; + u64 wwpn; + u64 wwnn; + u8 retry_count; + + /* Capabilities */ + u32 sg_supp:1; /* scatter gather supported */ + u32 seq_offload:1; /* seq offload supported */ + u32 crc_offload:1; /* crc offload supported */ + u32 lro_enabled:1; /* large receive offload */ + u32 mfs; /* max FC payload size */ + unsigned int service_params; + unsigned int e_d_tov; + unsigned int r_a_tov; + u8 max_retry_count; + u16 link_speed; + u16 link_supported_speeds; + u16 lro_xid; /* max xid for fcoe lro */ + struct fc_ns_fts fcts; /* FC-4 type masks */ + struct fc_els_rnid_gen rnid_gen; /* RNID information */ + + /* Semaphores */ + struct mutex lp_mutex; + + /* Miscellaneous */ + struct delayed_work retry_work; + struct delayed_work disc_work; +}; + +/* + * FC_LPORT HELPER FUNCTIONS + *****************************/ +static inline void *lport_priv(const struct fc_lport *lp) +{ + return (void *)(lp + 1); +} + +static inline int fc_lport_test_ready(struct fc_lport *lp) +{ + return lp->state == LPORT_ST_READY; +} + +static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwnn = wwnn; +} + +static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwpn = wwnn; +} + +static inline void fc_lport_state_enter(struct fc_lport *lp, + enum fc_lport_state state) +{ + if (state != lp->state) + lp->retry_count = 0; + lp->state = state; +} + + +/* + * LOCAL PORT LAYER + *****************************/ +int fc_lport_init(struct fc_lport *lp); + +/* + * Destroy the specified local port by finding and freeing all + * fc_rports associated with it and then by freeing the fc_lport + * itself. + */ +int fc_lport_destroy(struct fc_lport *lp); + +/* + * Logout the specified local port from the fabric + */ +int fc_fabric_logoff(struct fc_lport *lp); + +/* + * Initiate the LP state machine. This handler will use fc_host_attr + * to store the FLOGI service parameters, so fc_host_attr must be + * initialized before calling this handler. + */ +int fc_fabric_login(struct fc_lport *lp); + +/* + * The link is up for the given local port. + */ +void fc_linkup(struct fc_lport *); + +/* + * Link is down for the given local port. + */ +void fc_linkdown(struct fc_lport *); + +/* + * Configure the local port. + */ +int fc_lport_config(struct fc_lport *); + +/* + * Reset the local port. + */ +int fc_lport_reset(struct fc_lport *); + +/* + * Set the mfs or reset + */ +int fc_set_mfs(struct fc_lport *lp, u32 mfs); + + +/* + * REMOTE PORT LAYER + *****************************/ +int fc_rport_init(struct fc_lport *lp); +void fc_rport_terminate_io(struct fc_rport *rp); + +/* + * DISCOVERY LAYER + *****************************/ +int fc_disc_init(struct fc_lport *lp); + + +/* + * SCSI LAYER + *****************************/ +/* + * Initialize the SCSI block of libfc + */ +int fc_fcp_init(struct fc_lport *); + +/* + * This section provides an API which allows direct interaction + * with the SCSI-ml. Each of these functions satisfies a function + * pointer defined in Scsi_Host and therefore is always called + * directly from the SCSI-ml. + */ +int fc_queuecommand(struct scsi_cmnd *sc_cmd, + void (*done)(struct scsi_cmnd *)); + +/* + * complete processing of a fcp packet + * + * This function may sleep if a fsp timer is pending. + * The host lock must not be held by caller. + */ +void fc_fcp_complete(struct fc_fcp_pkt *fsp); + +/* + * Send an ABTS frame to the target device. The sc_cmd argument + * is a pointer to the SCSI command to be aborted. + */ +int fc_eh_abort(struct scsi_cmnd *sc_cmd); + +/* + * Reset a LUN by sending send the tm cmd to the target. + */ +int fc_eh_device_reset(struct scsi_cmnd *sc_cmd); + +/* + * Reset the host adapter. + */ +int fc_eh_host_reset(struct scsi_cmnd *sc_cmd); + +/* + * Check rport status. + */ +int fc_slave_alloc(struct scsi_device *sdev); + +/* + * Adjust the queue depth. + */ +int fc_change_queue_depth(struct scsi_device *sdev, int qdepth); + +/* + * Change the tag type. + */ +int fc_change_queue_type(struct scsi_device *sdev, int tag_type); + +/* + * Free memory pools used by the FCP layer. + */ +void fc_fcp_destroy(struct fc_lport *); + +/* + * ELS/CT interface + *****************************/ +/* + * Initializes ELS/CT interface + */ +int fc_elsct_init(struct fc_lport *lp); + + +/* + * EXCHANGE MANAGER LAYER + *****************************/ +/* + * Initializes Exchange Manager related + * function pointers in struct libfc_function_template. + */ +int fc_exch_init(struct fc_lport *lp); + +/* + * Allocates an Exchange Manager (EM). + * + * The EM manages exchanges for their allocation and + * free, also allows exchange lookup for received + * frame. + * + * The class is used for initializing FC class of + * allocated exchange from EM. + * + * The min_xid and max_xid will limit new + * exchange ID (XID) within this range for + * a new exchange. + * The LLD may choose to have multiple EMs, + * e.g. one EM instance per CPU receive thread in LLD. + * The LLD can use exch_get() of struct libfc_function_template + * to specify XID for a new exchange within + * a specified EM instance. + * + * The em_idx to uniquely identify an EM instance. + */ +struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, + enum fc_class class, + u16 min_xid, + u16 max_xid); + +/* + * Free an exchange manager. + */ +void fc_exch_mgr_free(struct fc_exch_mgr *mp); + +/* + * Receive a frame on specified local port and exchange manager. + */ +void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, + struct fc_frame *fp); + +/* + * This function is for exch_seq_send function pointer in + * struct libfc_function_template, see comment block on + * exch_seq_send for description of this function. + */ +struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, u32 timer_msec); + +/* + * send a frame using existing sequence and exchange. + */ +int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); + +/* + * Send ELS response using mainly infomation + * in exchange and sequence in EM layer. + */ +void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + +/* + * This function is for seq_exch_abort function pointer in + * struct libfc_function_template, see comment block on + * seq_exch_abort for description of this function. + */ +int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); + +/* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + */ +void fc_exch_done(struct fc_seq *sp); + +/* + * Assigns a EM and XID for a frame and then allocates + * a new exchange and sequence pair. + * The fp can be used to determine free XID. + */ +struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); + +/* + * Allocate a new exchange and sequence pair. + * if ex_id is zero then next free exchange id + * from specified exchange manger mp will be assigned. + */ +struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, + struct fc_frame *fp, u16 ex_id); +/* + * Start a new sequence on the same exchange as the supplied sequence. + */ +struct fc_seq *fc_seq_start_next(struct fc_seq *sp); + +/* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + */ +void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); + +/* + * Functions for fc_functions_template + */ +void fc_get_host_speed(struct Scsi_Host *shost); +void fc_get_host_port_type(struct Scsi_Host *shost); +void fc_get_host_port_state(struct Scsi_Host *shost); +void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); +struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); + +/* + * module setup functions. + */ +int fc_setup_exch_mgr(void); +void fc_destroy_exch_mgr(void); +int fc_setup_rport(void); +void fc_destroy_rport(void); + +#endif /* _LIBFC_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/libfcoe.h b/libdde_linux26/contrib/include/scsi/libfcoe.h new file mode 100644 index 00000000..941818f2 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libfcoe.h @@ -0,0 +1,171 @@ +/* + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFCOE_H +#define _LIBFCOE_H + +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <scsi/fc/fc_fcoe.h> +#include <scsi/libfc.h> + +/* + * this percpu struct for fcoe + */ +struct fcoe_percpu_s { + int cpu; + struct task_struct *thread; + struct sk_buff_head fcoe_rx_list; + struct page *crc_eof_page; + int crc_eof_offset; +}; + +/* + * the fcoe sw transport private data + */ +struct fcoe_softc { + struct list_head list; + struct fc_lport *lp; + struct net_device *real_dev; + struct net_device *phys_dev; /* device with ethtool_ops */ + struct packet_type fcoe_packet_type; + struct sk_buff_head fcoe_pending_queue; + u8 fcoe_pending_queue_active; + + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; + u8 data_src_addr[ETH_ALEN]; + /* + * fcoe protocol address learning related stuff + */ + u16 flogi_oxid; + u8 flogi_progress; + u8 address_mode; +}; + +static inline struct net_device *fcoe_netdev( + const struct fc_lport *lp) +{ + return ((struct fcoe_softc *)lport_priv(lp))->real_dev; +} + +static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) +{ + return (struct fcoe_hdr *)skb_network_header(skb); +} + +static inline int skb_fcoe_offset(const struct sk_buff *skb) +{ + return skb_network_offset(skb); +} + +static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) +{ + return (struct fc_frame_header *)skb_transport_header(skb); +} + +static inline int skb_fc_offset(const struct sk_buff *skb) +{ + return skb_transport_offset(skb); +} + +static inline void skb_reset_fc_header(struct sk_buff *skb) +{ + skb_reset_network_header(skb); + skb_set_transport_header(skb, skb_network_offset(skb) + + sizeof(struct fcoe_hdr)); +} + +static inline bool skb_fc_is_data(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; +} + +static inline bool skb_fc_is_cmd(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) +{ + return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); +} + +static inline bool skb_fc_is_roff(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; +} + +static inline u16 skb_fc_oxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); +} + +static inline u16 skb_fc_rxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); +} + +/* FIXME - DMA_BIDIRECTIONAL ? */ +#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0])) +#define skb_cmd(skb) (skb_cb(skb)->fr_cmd) +#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction) +static inline bool skb_fc_is_read(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_FROM_DEVICE; + return false; +} + +static inline bool skb_fc_is_write(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_TO_DEVICE; + return false; +} + +/* libfcoe funcs */ +int fcoe_reset(struct Scsi_Host *shost); +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], + unsigned int scheme, unsigned int port); + +u32 fcoe_fc_crc(struct fc_frame *fp); +int fcoe_xmit(struct fc_lport *, struct fc_frame *); +int fcoe_rcv(struct sk_buff *, struct net_device *, + struct packet_type *, struct net_device *); + +int fcoe_percpu_receive_thread(void *arg); +void fcoe_clean_pending_queue(struct fc_lport *lp); +void fcoe_percpu_clean(struct fc_lport *lp); +void fcoe_watchdog(ulong vp); +int fcoe_link_ok(struct fc_lport *lp); + +struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); +int fcoe_hostlist_add(const struct fc_lport *); +int fcoe_hostlist_remove(const struct fc_lport *); + +struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); +int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); + +/* fcoe sw hba */ +int __init fcoe_sw_init(void); +int __exit fcoe_sw_exit(void); +#endif /* _LIBFCOE_H */ diff --git a/libdde_linux26/contrib/include/scsi/libiscsi.h b/libdde_linux26/contrib/include/scsi/libiscsi.h new file mode 100644 index 00000000..7360e191 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libiscsi.h @@ -0,0 +1,438 @@ +/* + * iSCSI lib definitions + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 - 2006 Mike Christie + * Copyright (C) 2004 - 2005 Dmitry Yusupov + * Copyright (C) 2004 - 2005 Alex Aizman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef LIBISCSI_H +#define LIBISCSI_H + +#include <linux/types.h> +#include <linux/wait.h> +#include <linux/mutex.h> +#include <linux/timer.h> +#include <linux/workqueue.h> +#include <scsi/iscsi_proto.h> +#include <scsi/iscsi_if.h> +#include <scsi/scsi_transport_iscsi.h> + +struct scsi_transport_template; +struct scsi_host_template; +struct scsi_device; +struct Scsi_Host; +struct scsi_cmnd; +struct socket; +struct iscsi_transport; +struct iscsi_cls_session; +struct iscsi_cls_conn; +struct iscsi_session; +struct iscsi_nopin; +struct device; + +/* #define DEBUG_SCSI */ +#ifdef DEBUG_SCSI +#define debug_scsi(fmt...) printk(KERN_INFO "iscsi: " fmt) +#else +#define debug_scsi(fmt...) +#endif + +#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ +#define ISCSI_MGMT_CMDS_MAX 15 + +#define ISCSI_DEF_CMD_PER_LUN 32 +#define ISCSI_MAX_CMD_PER_LUN 128 + +/* Task Mgmt states */ +enum { + TMF_INITIAL, + TMF_QUEUED, + TMF_SUCCESS, + TMF_FAILED, + TMF_TIMEDOUT, + TMF_NOT_FOUND, +}; + +/* Connection suspend "bit" */ +#define ISCSI_SUSPEND_BIT 1 + +#define ISCSI_ITT_MASK 0x1fff +#define ISCSI_TOTAL_CMDS_MAX 4096 +/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ +#define ISCSI_TOTAL_CMDS_MIN 16 +#define ISCSI_AGE_SHIFT 28 +#define ISCSI_AGE_MASK 0xf + +#define ISCSI_ADDRESS_BUF_LEN 64 + +enum { + /* this is the maximum possible storage for AHSs */ + ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) + + sizeof(struct iscsi_rlength_ahdr), + ISCSI_DIGEST_SIZE = sizeof(__u32), +}; + + +enum { + ISCSI_TASK_COMPLETED, + ISCSI_TASK_PENDING, + ISCSI_TASK_RUNNING, +}; + +struct iscsi_r2t_info { + __be32 ttt; /* copied from R2T */ + __be32 exp_statsn; /* copied from R2T */ + uint32_t data_length; /* copied from R2T */ + uint32_t data_offset; /* copied from R2T */ + int data_count; /* DATA-Out payload progress */ + int datasn; + /* LLDs should set/update these values */ + int sent; /* R2T sequence progress */ +}; + +struct iscsi_task { + /* + * Because LLDs allocate their hdr differently, this is a pointer + * and length to that storage. It must be setup at session + * creation time. + */ + struct iscsi_hdr *hdr; + unsigned short hdr_max; + unsigned short hdr_len; /* accumulated size of hdr used */ + /* copied values in case we need to send tmfs */ + itt_t hdr_itt; + __be32 cmdsn; + uint8_t lun[8]; + + int itt; /* this ITT */ + + unsigned imm_count; /* imm-data (bytes) */ + /* offset in unsolicited stream (bytes); */ + struct iscsi_r2t_info unsol_r2t; + char *data; /* mgmt payload */ + unsigned data_count; + struct scsi_cmnd *sc; /* associated SCSI cmd*/ + struct iscsi_conn *conn; /* used connection */ + + /* state set/tested under session->lock */ + int state; + atomic_t refcount; + struct list_head running; /* running cmd list */ + void *dd_data; /* driver/transport data */ +}; + +static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) +{ + return task->unsol_r2t.data_length > task->unsol_r2t.sent; +} + +static inline void* iscsi_next_hdr(struct iscsi_task *task) +{ + return (void*)task->hdr + task->hdr_len; +} + +/* Connection's states */ +enum { + ISCSI_CONN_INITIAL_STAGE, + ISCSI_CONN_STARTED, + ISCSI_CONN_STOPPED, + ISCSI_CONN_CLEANUP_WAIT, +}; + +struct iscsi_conn { + struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ + void *dd_data; /* iscsi_transport data */ + struct iscsi_session *session; /* parent session */ + /* + * conn_stop() flag: stop to recover, stop to terminate + */ + int stop_stage; + struct timer_list transport_timer; + unsigned long last_recv; + unsigned long last_ping; + int ping_timeout; + int recv_timeout; + struct iscsi_task *ping_task; + + /* iSCSI connection-wide sequencing */ + uint32_t exp_statsn; + + /* control data */ + int id; /* CID */ + int c_stage; /* connection state */ + /* + * Preallocated buffer for pdus that have data but do not + * originate from scsi-ml. We never have two pdus using the + * buffer at the same time. It is only allocated to + * the default max recv size because the pdus we support + * should always fit in this buffer + */ + char *data; + struct iscsi_task *login_task; /* mtask used for login/text */ + struct iscsi_task *task; /* xmit task in progress */ + + /* xmit */ + struct list_head mgmtqueue; /* mgmt (control) xmit queue */ + struct list_head mgmt_run_list; /* list of control tasks */ + struct list_head xmitqueue; /* data-path cmd queue */ + struct list_head run_list; /* list of cmds in progress */ + struct list_head requeue; /* tasks needing another run */ + struct work_struct xmitwork; /* per-conn. xmit workqueue */ + unsigned long suspend_tx; /* suspend Tx */ + unsigned long suspend_rx; /* suspend Rx */ + + /* abort */ + wait_queue_head_t ehwait; /* used in eh_abort() */ + struct iscsi_tm tmhdr; + struct timer_list tmf_timer; + int tmf_state; /* see TMF_INITIAL, etc.*/ + + /* negotiated params */ + unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ + unsigned max_xmit_dlength; /* target_max_recv_dsl */ + int hdrdgst_en; + int datadgst_en; + int ifmarker_en; + int ofmarker_en; + /* values userspace uses to id a conn */ + int persistent_port; + char *persistent_address; + /* remote portal currently connected to */ + int portal_port; + char portal_address[ISCSI_ADDRESS_BUF_LEN]; + + /* MIB-statistics */ + uint64_t txdata_octets; + uint64_t rxdata_octets; + uint32_t scsicmd_pdus_cnt; + uint32_t dataout_pdus_cnt; + uint32_t scsirsp_pdus_cnt; + uint32_t datain_pdus_cnt; + uint32_t r2t_pdus_cnt; + uint32_t tmfcmd_pdus_cnt; + int32_t tmfrsp_pdus_cnt; + + /* custom statistics */ + uint32_t eh_abort_cnt; + uint32_t fmr_unalign_cnt; +}; + +struct iscsi_pool { + struct kfifo *queue; /* FIFO Queue */ + void **pool; /* Pool of elements */ + int max; /* Max number of elements */ +}; + +/* Session's states */ +enum { + ISCSI_STATE_FREE = 1, + ISCSI_STATE_LOGGED_IN, + ISCSI_STATE_FAILED, + ISCSI_STATE_TERMINATE, + ISCSI_STATE_IN_RECOVERY, + ISCSI_STATE_RECOVERY_FAILED, + ISCSI_STATE_LOGGING_OUT, +}; + +struct iscsi_session { + struct iscsi_cls_session *cls_session; + /* + * Syncs up the scsi eh thread with the iscsi eh thread when sending + * task management functions. This must be taken before the session + * and recv lock. + */ + struct mutex eh_mutex; + + /* iSCSI session-wide sequencing */ + uint32_t cmdsn; + uint32_t exp_cmdsn; + uint32_t max_cmdsn; + + /* This tracks the reqs queued into the initiator */ + uint32_t queued_cmdsn; + + /* configuration */ + int abort_timeout; + int lu_reset_timeout; + int initial_r2t_en; + unsigned max_r2t; + int imm_data_en; + unsigned first_burst; + unsigned max_burst; + int time2wait; + int time2retain; + int pdu_inorder_en; + int dataseq_inorder_en; + int erl; + int fast_abort; + int tpgt; + char *username; + char *username_in; + char *password; + char *password_in; + char *targetname; + char *ifacename; + char *initiatorname; + /* control data */ + struct iscsi_transport *tt; + struct Scsi_Host *host; + struct iscsi_conn *leadconn; /* leading connection */ + spinlock_t lock; /* protects session state, * + * sequence numbers, * + * session resources: * + * - cmdpool, * + * - mgmtpool, * + * - r2tpool */ + int state; /* session state */ + int age; /* counts session re-opens */ + + int scsi_cmds_max; /* max scsi commands */ + int cmds_max; /* size of cmds array */ + struct iscsi_task **cmds; /* Original Cmds arr */ + struct iscsi_pool cmdpool; /* PDU's pool */ +}; + +enum { + ISCSI_HOST_SETUP, + ISCSI_HOST_REMOVED, +}; + +struct iscsi_host { + char *initiatorname; + /* hw address or netdev iscsi connection is bound to */ + char *hwaddress; + char *netdev; + /* local address */ + int local_port; + char local_address[ISCSI_ADDRESS_BUF_LEN]; + + wait_queue_head_t session_removal_wq; + /* protects sessions and state */ + spinlock_t lock; + int num_sessions; + int state; +}; + +/* + * scsi host template + */ +extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); +extern int iscsi_eh_abort(struct scsi_cmnd *sc); +extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); +extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); +extern int iscsi_queuecommand(struct scsi_cmnd *sc, + void (*done)(struct scsi_cmnd *)); + +/* + * iSCSI host helpers. + */ +#define iscsi_host_priv(_shost) \ + (shost_priv(_shost) + sizeof(struct iscsi_host)) + +extern int iscsi_host_set_param(struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf, + int buflen); +extern int iscsi_host_get_param(struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf); +extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); +extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, + int dd_data_size, uint16_t qdepth); +extern void iscsi_host_remove(struct Scsi_Host *shost); +extern void iscsi_host_free(struct Scsi_Host *shost); + +/* + * session management + */ +extern struct iscsi_cls_session * +iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, + uint16_t, int, uint32_t, unsigned int); +extern void iscsi_session_teardown(struct iscsi_cls_session *); +extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); +extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, + enum iscsi_param param, char *buf, int buflen); +extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, + enum iscsi_param param, char *buf); + +#define iscsi_session_printk(prefix, _sess, fmt, a...) \ + iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) + +/* + * connection management + */ +extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, + int, uint32_t); +extern void iscsi_conn_teardown(struct iscsi_cls_conn *); +extern int iscsi_conn_start(struct iscsi_cls_conn *); +extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); +extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, + int); +extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); +extern void iscsi_session_failure(struct iscsi_cls_session *cls_session, + enum iscsi_err err); +extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, + enum iscsi_param param, char *buf); +extern void iscsi_suspend_tx(struct iscsi_conn *conn); + +#define iscsi_conn_printk(prefix, _c, fmt, a...) \ + iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ + fmt, ##a) + +/* + * pdu and task processing + */ +extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); +extern void iscsi_prep_data_out_pdu(struct iscsi_task *task, + struct iscsi_r2t_info *r2t, + struct iscsi_data *hdr); +extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, + char *, uint32_t); +extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, + char *, int); +extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, + char *, int); +extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); +extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); +extern void iscsi_requeue_task(struct iscsi_task *task); +extern void iscsi_put_task(struct iscsi_task *task); +extern void __iscsi_get_task(struct iscsi_task *task); + +/* + * generic helpers + */ +extern void iscsi_pool_free(struct iscsi_pool *); +extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int); + +/* + * inline functions to deal with padding. + */ +static inline unsigned int +iscsi_padded(unsigned int len) +{ + return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1); +} + +static inline unsigned int +iscsi_padding(unsigned int len) +{ + len &= (ISCSI_PAD_LEN - 1); + if (len) + len = ISCSI_PAD_LEN - len; + return len; +} + +#endif diff --git a/libdde_linux26/contrib/include/scsi/libiscsi_tcp.h b/libdde_linux26/contrib/include/scsi/libiscsi_tcp.h new file mode 100644 index 00000000..9e3182e6 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libiscsi_tcp.h @@ -0,0 +1,133 @@ +/* + * iSCSI over TCP/IP Data-Path lib + * + * Copyright (C) 2008 Mike Christie + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef LIBISCSI_TCP_H +#define LIBISCSI_TCP_H + +#include <scsi/libiscsi.h> + +struct iscsi_tcp_conn; +struct iscsi_segment; +struct sk_buff; +struct hash_desc; + +typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, + struct iscsi_segment *); + +struct iscsi_segment { + unsigned char *data; + unsigned int size; + unsigned int copied; + unsigned int total_size; + unsigned int total_copied; + + struct hash_desc *hash; + unsigned char padbuf[ISCSI_PAD_LEN]; + unsigned char recv_digest[ISCSI_DIGEST_SIZE]; + unsigned char digest[ISCSI_DIGEST_SIZE]; + unsigned int digest_len; + + struct scatterlist *sg; + void *sg_mapped; + unsigned int sg_offset; + + iscsi_segment_done_fn_t *done; +}; + +/* Socket connection recieve helper */ +struct iscsi_tcp_recv { + struct iscsi_hdr *hdr; + struct iscsi_segment segment; + + /* Allocate buffer for BHS + AHS */ + uint32_t hdr_buf[64]; + + /* copied and flipped values */ + int datalen; +}; + +struct iscsi_tcp_conn { + struct iscsi_conn *iscsi_conn; + void *dd_data; + int stop_stage; /* conn_stop() flag: * + * stop to recover, * + * stop to terminate */ + /* control data */ + struct iscsi_tcp_recv in; /* TCP receive context */ + /* CRC32C (Rx) LLD should set this is they do not offload */ + struct hash_desc *rx_hash; +}; + +struct iscsi_tcp_task { + uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ + int data_offset; + struct iscsi_r2t_info *r2t; /* in progress solict R2T */ + struct iscsi_pool r2tpool; + struct kfifo *r2tqueue; + void *dd_data; +}; + +enum { + ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ + ISCSI_TCP_SKB_DONE, /* skb is out of data */ + ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ + ISCSI_TCP_SUSPENDED, /* conn is suspended */ +}; + +extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, + unsigned int offset, bool offloaded, int *status); +extern void iscsi_tcp_cleanup_task(struct iscsi_task *task); +extern int iscsi_tcp_task_init(struct iscsi_task *task); +extern int iscsi_tcp_task_xmit(struct iscsi_task *task); + +/* segment helpers */ +extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, + struct iscsi_segment *segment, int recv, + unsigned copied); +extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); + +extern void iscsi_segment_init_linear(struct iscsi_segment *segment, + void *data, size_t size, + iscsi_segment_done_fn_t *done, + struct hash_desc *hash); +extern int +iscsi_segment_seek_sg(struct iscsi_segment *segment, + struct scatterlist *sg_list, unsigned int sg_count, + unsigned int offset, size_t size, + iscsi_segment_done_fn_t *done, struct hash_desc *hash); + +/* digest helpers */ +extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr, + size_t hdrlen, + unsigned char digest[ISCSI_DIGEST_SIZE]); +extern struct iscsi_cls_conn * +iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, + uint32_t conn_idx); +extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); + +/* misc helpers */ +extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); +extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); + +extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, + struct iscsi_stats *stats); +#endif /* LIBISCSI_TCP_H */ diff --git a/libdde_linux26/contrib/include/scsi/libsas.h b/libdde_linux26/contrib/include/scsi/libsas.h new file mode 100644 index 00000000..e78d3b62 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libsas.h @@ -0,0 +1,681 @@ +/* + * SAS host prototypes and structures header file + * + * Copyright (C) 2005 Adaptec, Inc. All rights reserved. + * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> + * + * This file is licensed under GPLv2. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _LIBSAS_H_ +#define _LIBSAS_H_ + + +#include <linux/timer.h> +#include <linux/pci.h> +#include <scsi/sas.h> +#include <linux/libata.h> +#include <linux/list.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_transport_sas.h> +#include <linux/scatterlist.h> + +struct block_device; + +enum sas_class { + SAS, + EXPANDER +}; + +enum sas_phy_role { + PHY_ROLE_NONE = 0, + PHY_ROLE_TARGET = 0x40, + PHY_ROLE_INITIATOR = 0x80, +}; + +enum sas_phy_type { + PHY_TYPE_PHYSICAL, + PHY_TYPE_VIRTUAL +}; + +/* The events are mnemonically described in sas_dump.c + * so when updating/adding events here, please also + * update the other file too. + */ +enum ha_event { + HAE_RESET = 0U, + HA_NUM_EVENTS = 1, +}; + +enum port_event { + PORTE_BYTES_DMAED = 0U, + PORTE_BROADCAST_RCVD = 1, + PORTE_LINK_RESET_ERR = 2, + PORTE_TIMER_EVENT = 3, + PORTE_HARD_RESET = 4, + PORT_NUM_EVENTS = 5, +}; + +enum phy_event { + PHYE_LOSS_OF_SIGNAL = 0U, + PHYE_OOB_DONE = 1, + PHYE_OOB_ERROR = 2, + PHYE_SPINUP_HOLD = 3, /* hot plug SATA, no COMWAKE sent */ + PHY_NUM_EVENTS = 4, +}; + +enum discover_event { + DISCE_DISCOVER_DOMAIN = 0U, + DISCE_REVALIDATE_DOMAIN = 1, + DISCE_PORT_GONE = 2, + DISC_NUM_EVENTS = 3, +}; + +/* ---------- Expander Devices ---------- */ + +#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj) +#define to_dev_attr(_attr) container_of(_attr, struct domain_dev_attribute,\ + attr) + +enum routing_attribute { + DIRECT_ROUTING, + SUBTRACTIVE_ROUTING, + TABLE_ROUTING, +}; + +enum ex_phy_state { + PHY_EMPTY, + PHY_VACANT, + PHY_NOT_PRESENT, + PHY_DEVICE_DISCOVERED +}; + +struct ex_phy { + int phy_id; + + enum ex_phy_state phy_state; + + enum sas_dev_type attached_dev_type; + enum sas_linkrate linkrate; + + u8 attached_sata_host:1; + u8 attached_sata_dev:1; + u8 attached_sata_ps:1; + + enum sas_protocol attached_tproto; + enum sas_protocol attached_iproto; + + u8 attached_sas_addr[SAS_ADDR_SIZE]; + u8 attached_phy_id; + + u8 phy_change_count; + enum routing_attribute routing_attr; + u8 virtual:1; + + int last_da_index; + + struct sas_phy *phy; + struct sas_port *port; +}; + +struct expander_device { + struct list_head children; + + u16 ex_change_count; + u16 max_route_indexes; + u8 num_phys; + u8 configuring:1; + u8 conf_route_table:1; + u8 enclosure_logical_id[8]; + + struct ex_phy *ex_phy; + struct sas_port *parent_port; +}; + +/* ---------- SATA device ---------- */ +enum ata_command_set { + ATA_COMMAND_SET = 0, + ATAPI_COMMAND_SET = 1, +}; + +struct sata_device { + enum ata_command_set command_set; + struct smp_resp rps_resp; /* report_phy_sata_resp */ + __le16 *identify_device; + __le16 *identify_packet_device; + + u8 port_no; /* port number, if this is a PM (Port) */ + struct list_head children; /* PM Ports if this is a PM */ + + struct ata_port *ap; + struct ata_host ata_host; + struct ata_taskfile tf; + u32 sstatus; + u32 serror; + u32 scontrol; +}; + +/* ---------- Domain device ---------- */ +struct domain_device { + enum sas_dev_type dev_type; + + enum sas_linkrate linkrate; + enum sas_linkrate min_linkrate; + enum sas_linkrate max_linkrate; + + int pathways; + + struct domain_device *parent; + struct list_head siblings; /* devices on the same level */ + struct asd_sas_port *port; /* shortcut to root of the tree */ + + struct list_head dev_list_node; + + enum sas_protocol iproto; + enum sas_protocol tproto; + + struct sas_rphy *rphy; + + u8 sas_addr[SAS_ADDR_SIZE]; + u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE]; + + u8 frame_rcvd[32]; + + union { + struct expander_device ex_dev; + struct sata_device sata_dev; /* STP & directly attached */ + }; + + void *lldd_dev; +}; + +struct sas_discovery_event { + struct work_struct work; + struct asd_sas_port *port; +}; + +struct sas_discovery { + spinlock_t disc_event_lock; + struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; + unsigned long pending; + u8 fanout_sas_addr[8]; + u8 eeds_a[8]; + u8 eeds_b[8]; + int max_level; +}; + + +/* The port struct is Class:RW, driver:RO */ +struct asd_sas_port { +/* private: */ + struct completion port_gone_completion; + + struct sas_discovery disc; + struct domain_device *port_dev; + spinlock_t dev_list_lock; + struct list_head dev_list; + enum sas_linkrate linkrate; + + struct sas_phy *phy; + struct work_struct work; + +/* public: */ + int id; + + enum sas_class class; + u8 sas_addr[SAS_ADDR_SIZE]; + u8 attached_sas_addr[SAS_ADDR_SIZE]; + enum sas_protocol iproto; + enum sas_protocol tproto; + + enum sas_oob_mode oob_mode; + + spinlock_t phy_list_lock; + struct list_head phy_list; + int num_phys; + u32 phy_mask; + + struct sas_ha_struct *ha; + + struct sas_port *port; + + void *lldd_port; /* not touched by the sas class code */ +}; + +struct asd_sas_event { + struct work_struct work; + struct asd_sas_phy *phy; +}; + +/* The phy pretty much is controlled by the LLDD. + * The class only reads those fields. + */ +struct asd_sas_phy { +/* private: */ + /* protected by ha->event_lock */ + struct asd_sas_event port_events[PORT_NUM_EVENTS]; + struct asd_sas_event phy_events[PHY_NUM_EVENTS]; + + unsigned long port_events_pending; + unsigned long phy_events_pending; + + int error; + + struct sas_phy *phy; + +/* public: */ + /* The following are class:RO, driver:R/W */ + int enabled; /* must be set */ + + int id; /* must be set */ + enum sas_class class; + enum sas_protocol iproto; + enum sas_protocol tproto; + + enum sas_phy_type type; + enum sas_phy_role role; + enum sas_oob_mode oob_mode; + enum sas_linkrate linkrate; + + u8 *sas_addr; /* must be set */ + u8 attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */ + + spinlock_t frame_rcvd_lock; + u8 *frame_rcvd; /* must be set */ + int frame_rcvd_size; + + spinlock_t sas_prim_lock; + u32 sas_prim; + + struct list_head port_phy_el; /* driver:RO */ + struct asd_sas_port *port; /* Class:RW, driver: RO */ + + struct sas_ha_struct *ha; /* may be set; the class sets it anyway */ + + void *lldd_phy; /* not touched by the sas_class_code */ +}; + +struct scsi_core { + struct Scsi_Host *shost; + + spinlock_t task_queue_lock; + struct list_head task_queue; + int task_queue_size; + + struct task_struct *queue_thread; +}; + +struct sas_ha_event { + struct work_struct work; + struct sas_ha_struct *ha; +}; + +enum sas_ha_state { + SAS_HA_REGISTERED, + SAS_HA_UNREGISTERED +}; + +struct sas_ha_struct { +/* private: */ + spinlock_t event_lock; + struct sas_ha_event ha_events[HA_NUM_EVENTS]; + unsigned long pending; + + enum sas_ha_state state; + spinlock_t state_lock; + + struct scsi_core core; + +/* public: */ + char *sas_ha_name; + struct device *dev; /* should be set */ + struct module *lldd_module; /* should be set */ + + u8 *sas_addr; /* must be set */ + u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE]; + + spinlock_t phy_port_lock; + struct asd_sas_phy **sas_phy; /* array of valid pointers, must be set */ + struct asd_sas_port **sas_port; /* array of valid pointers, must be set */ + int num_phys; /* must be set, gt 0, static */ + + /* The class calls this to send a task for execution. */ + int lldd_max_execute_num; + int lldd_queue_size; + + /* LLDD calls these to notify the class of an event. */ + void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event); + void (*notify_port_event)(struct asd_sas_phy *, enum port_event); + void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event); + + void *lldd_ha; /* not touched by sas class code */ + + struct list_head eh_done_q; +}; + +#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata) + +static inline struct domain_device * +starget_to_domain_dev(struct scsi_target *starget) { + return starget->hostdata; +} + +static inline struct domain_device * +sdev_to_domain_dev(struct scsi_device *sdev) { + return starget_to_domain_dev(sdev->sdev_target); +} + +static inline struct domain_device * +cmd_to_domain_dev(struct scsi_cmnd *cmd) +{ + return sdev_to_domain_dev(cmd->device); +} + +void sas_hash_addr(u8 *hashed, const u8 *sas_addr); + +/* Before calling a notify event, LLDD should use this function + * when the link is severed (possibly from its tasklet). + * The idea is that the Class only reads those, while the LLDD, + * can R/W these (thus avoiding a race). + */ +static inline void sas_phy_disconnected(struct asd_sas_phy *phy) +{ + phy->oob_mode = OOB_NOT_CONNECTED; + phy->linkrate = SAS_LINK_RATE_UNKNOWN; +} + +/* ---------- Tasks ---------- */ +/* + service_response | SAS_TASK_COMPLETE | SAS_TASK_UNDELIVERED | + exec_status | | | + ---------------------+---------------------+-----------------------+ + SAM_... | X | | + DEV_NO_RESPONSE | X | X | + INTERRUPTED | X | | + QUEUE_FULL | | X | + DEVICE_UNKNOWN | | X | + SG_ERR | | X | + ---------------------+---------------------+-----------------------+ + */ + +enum service_response { + SAS_TASK_COMPLETE, + SAS_TASK_UNDELIVERED = -1, +}; + +enum exec_status { + SAM_GOOD = 0, + SAM_CHECK_COND = 2, + SAM_COND_MET = 4, + SAM_BUSY = 8, + SAM_INTERMEDIATE = 0x10, + SAM_IM_COND_MET = 0x12, + SAM_RESV_CONFLICT= 0x14, + SAM_TASK_SET_FULL= 0x28, + SAM_ACA_ACTIVE = 0x30, + SAM_TASK_ABORTED = 0x40, + + SAS_DEV_NO_RESPONSE = 0x80, + SAS_DATA_UNDERRUN, + SAS_DATA_OVERRUN, + SAS_INTERRUPTED, + SAS_QUEUE_FULL, + SAS_DEVICE_UNKNOWN, + SAS_SG_ERR, + SAS_OPEN_REJECT, + SAS_OPEN_TO, + SAS_PROTO_RESPONSE, + SAS_PHY_DOWN, + SAS_NAK_R_ERR, + SAS_PENDING, + SAS_ABORTED_TASK, +}; + +/* When a task finishes with a response, the LLDD examines the + * response: + * - For an ATA task task_status_struct::stat is set to + * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the + * contents of struct ata_task_resp. + * - For SSP tasks, if no data is present or status/TMF response + * is valid, task_status_struct::stat is set. If data is present + * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets + * task_status_struct::buf_valid_size, and task_status_struct::stat is + * set to SAM_CHECK_COND. + * + * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp + * for ATA task. + * + * "frame_len" is the total frame length, which could be more or less + * than actually copied. + * + * Tasks ending with response, always set the residual field. + */ +struct ata_task_resp { + u16 frame_len; + u8 ending_fis[24]; /* dev to host or data-in */ + u32 sstatus; + u32 serror; + u32 scontrol; + u32 sactive; +}; + +#define SAS_STATUS_BUF_SIZE 96 + +struct task_status_struct { + enum service_response resp; + enum exec_status stat; + int buf_valid_size; + + u8 buf[SAS_STATUS_BUF_SIZE]; + + u32 residual; + enum sas_open_rej_reason open_rej_reason; +}; + +/* ATA and ATAPI task queuable to a SAS LLDD. + */ +struct sas_ata_task { + struct host_to_dev_fis fis; + u8 atapi_packet[16]; /* 0 if not ATAPI task */ + + u8 retry_count; /* hardware retry, should be > 0 */ + + u8 dma_xfer:1; /* PIO:0 or DMA:1 */ + u8 use_ncq:1; + u8 set_affil_pol:1; + u8 stp_affil_pol:1; + + u8 device_control_reg_update:1; +}; + +struct sas_smp_task { + struct scatterlist smp_req; + struct scatterlist smp_resp; +}; + +enum task_attribute { + TASK_ATTR_SIMPLE = 0, + TASK_ATTR_HOQ = 1, + TASK_ATTR_ORDERED= 2, + TASK_ATTR_ACA = 4, +}; + +struct sas_ssp_task { + u8 retry_count; /* hardware retry, should be > 0 */ + + u8 LUN[8]; + u8 enable_first_burst:1; + enum task_attribute task_attr; + u8 task_prio; + u8 cdb[16]; +}; + +struct sas_task { + struct domain_device *dev; + struct list_head list; + + spinlock_t task_state_lock; + unsigned task_state_flags; + + enum sas_protocol task_proto; + + /* Used by the discovery code. */ + struct timer_list timer; + struct completion completion; + + union { + struct sas_ata_task ata_task; + struct sas_smp_task smp_task; + struct sas_ssp_task ssp_task; + }; + + struct scatterlist *scatter; + int num_scatter; + u32 total_xfer_len; + u8 data_dir:2; /* Use PCI_DMA_... */ + + struct task_status_struct task_status; + void (*task_done)(struct sas_task *); + + void *lldd_task; /* for use by LLDDs */ + void *uldd_task; + + struct work_struct abort_work; +}; + +extern struct kmem_cache *sas_task_cache; + +#define SAS_TASK_STATE_PENDING 1 +#define SAS_TASK_STATE_DONE 2 +#define SAS_TASK_STATE_ABORTED 4 +#define SAS_TASK_NEED_DEV_RESET 8 +#define SAS_TASK_AT_INITIATOR 16 + +static inline struct sas_task *sas_alloc_task(gfp_t flags) +{ + struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags); + + if (task) { + INIT_LIST_HEAD(&task->list); + spin_lock_init(&task->task_state_lock); + task->task_state_flags = SAS_TASK_STATE_PENDING; + init_timer(&task->timer); + init_completion(&task->completion); + } + + return task; +} + +static inline void sas_free_task(struct sas_task *task) +{ + if (task) { + BUG_ON(!list_empty(&task->list)); + kmem_cache_free(sas_task_cache, task); + } +} + +struct sas_domain_function_template { + /* The class calls these to notify the LLDD of an event. */ + void (*lldd_port_formed)(struct asd_sas_phy *); + void (*lldd_port_deformed)(struct asd_sas_phy *); + + /* The class calls these when a device is found or gone. */ + int (*lldd_dev_found)(struct domain_device *); + void (*lldd_dev_gone)(struct domain_device *); + + int (*lldd_execute_task)(struct sas_task *, int num, + gfp_t gfp_flags); + + /* Task Management Functions. Must be called from process context. */ + int (*lldd_abort_task)(struct sas_task *); + int (*lldd_abort_task_set)(struct domain_device *, u8 *lun); + int (*lldd_clear_aca)(struct domain_device *, u8 *lun); + int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); + int (*lldd_I_T_nexus_reset)(struct domain_device *); + int (*lldd_lu_reset)(struct domain_device *, u8 *lun); + int (*lldd_query_task)(struct sas_task *); + + /* Port and Adapter management */ + int (*lldd_clear_nexus_port)(struct asd_sas_port *); + int (*lldd_clear_nexus_ha)(struct sas_ha_struct *); + + /* Phy management */ + int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *); +}; + +extern int sas_register_ha(struct sas_ha_struct *); +extern int sas_unregister_ha(struct sas_ha_struct *); + +int sas_set_phy_speed(struct sas_phy *phy, + struct sas_phy_linkrates *rates); +int sas_phy_enable(struct sas_phy *phy, int enabled); +int sas_phy_reset(struct sas_phy *phy, int hard_reset); +int sas_queue_up(struct sas_task *task); +extern int sas_queuecommand(struct scsi_cmnd *, + void (*scsi_done)(struct scsi_cmnd *)); +extern int sas_target_alloc(struct scsi_target *); +extern int sas_slave_alloc(struct scsi_device *); +extern int sas_slave_configure(struct scsi_device *); +extern void sas_slave_destroy(struct scsi_device *); +extern int sas_change_queue_depth(struct scsi_device *, int new_depth); +extern int sas_change_queue_type(struct scsi_device *, int qt); +extern int sas_bios_param(struct scsi_device *, + struct block_device *, + sector_t capacity, int *hsc); +extern struct scsi_transport_template * +sas_domain_attach_transport(struct sas_domain_function_template *); +extern void sas_domain_release_transport(struct scsi_transport_template *); + +int sas_discover_root_expander(struct domain_device *); + +void sas_init_ex_attr(void); + +int sas_ex_revalidate_domain(struct domain_device *); + +void sas_unregister_domain_devices(struct asd_sas_port *port); +void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *); +int sas_discover_event(struct asd_sas_port *, enum discover_event ev); + +int sas_discover_sata(struct domain_device *); +int sas_discover_end_dev(struct domain_device *); + +void sas_unregister_dev(struct domain_device *); + +void sas_init_dev(struct domain_device *); + +void sas_task_abort(struct sas_task *); +int __sas_task_abort(struct sas_task *); +int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); +int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); + +extern void sas_target_destroy(struct scsi_target *); +extern int sas_slave_alloc(struct scsi_device *); +extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); + +extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, + struct request *req); + +extern void sas_ssp_task_response(struct device *dev, struct sas_task *task, + struct ssp_response_iu *iu); +struct sas_phy *sas_find_local_phy(struct domain_device *dev); + +int sas_request_addr(struct Scsi_Host *shost, u8 *addr); + +#endif /* _SASLIB_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/libsrp.h b/libdde_linux26/contrib/include/scsi/libsrp.h new file mode 100644 index 00000000..ba615e4c --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/libsrp.h @@ -0,0 +1,77 @@ +#ifndef __LIBSRP_H__ +#define __LIBSRP_H__ + +#include <linux/list.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> +#include <scsi/srp.h> + +enum iue_flags { + V_DIOVER, + V_WRITE, + V_LINKED, + V_FLYING, +}; + +struct srp_buf { + dma_addr_t dma; + void *buf; +}; + +struct srp_queue { + void *pool; + void *items; + struct kfifo *queue; + spinlock_t lock; +}; + +struct srp_target { + struct Scsi_Host *shost; + struct device *dev; + + spinlock_t lock; + struct list_head cmd_queue; + + size_t srp_iu_size; + struct srp_queue iu_queue; + size_t rx_ring_size; + struct srp_buf **rx_ring; + + void *ldata; +}; + +struct iu_entry { + struct srp_target *target; + + struct list_head ilist; + dma_addr_t remote_token; + unsigned long flags; + + struct srp_buf *sbuf; +}; + +typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int, + struct srp_direct_buf *, int, + enum dma_data_direction, unsigned int); +extern int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t); +extern void srp_target_free(struct srp_target *); + +extern struct iu_entry *srp_iu_get(struct srp_target *); +extern void srp_iu_put(struct iu_entry *); + +extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64, u64); +extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, + srp_rdma_t, int, int); + + +static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host) +{ + return (struct srp_target *) host->hostdata; +} + +static inline int srp_cmd_direction(struct srp_cmd *cmd) +{ + return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; +} + +#endif diff --git a/libdde_linux26/contrib/include/scsi/sas.h b/libdde_linux26/contrib/include/scsi/sas.h new file mode 100644 index 00000000..e9fd0228 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/sas.h @@ -0,0 +1,630 @@ +/* + * SAS structures and definitions header file + * + * Copyright (C) 2005 Adaptec, Inc. All rights reserved. + * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> + * + * This file is licensed under GPLv2. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _SAS_H_ +#define _SAS_H_ + +#include <linux/types.h> +#include <asm/byteorder.h> + +#define SAS_ADDR_SIZE 8 +#define HASHED_SAS_ADDR_SIZE 3 +#define SAS_ADDR(_sa) ((unsigned long long) be64_to_cpu(*(__be64 *)(_sa))) + +#define SMP_REQUEST 0x40 +#define SMP_RESPONSE 0x41 + +#define SSP_DATA 0x01 +#define SSP_XFER_RDY 0x05 +#define SSP_COMMAND 0x06 +#define SSP_RESPONSE 0x07 +#define SSP_TASK 0x16 + +#define SMP_REPORT_GENERAL 0x00 +#define SMP_REPORT_MANUF_INFO 0x01 +#define SMP_READ_GPIO_REG 0x02 +#define SMP_DISCOVER 0x10 +#define SMP_REPORT_PHY_ERR_LOG 0x11 +#define SMP_REPORT_PHY_SATA 0x12 +#define SMP_REPORT_ROUTE_INFO 0x13 +#define SMP_WRITE_GPIO_REG 0x82 +#define SMP_CONF_ROUTE_INFO 0x90 +#define SMP_PHY_CONTROL 0x91 +#define SMP_PHY_TEST_FUNCTION 0x92 + +#define SMP_RESP_FUNC_ACC 0x00 +#define SMP_RESP_FUNC_UNK 0x01 +#define SMP_RESP_FUNC_FAILED 0x02 +#define SMP_RESP_INV_FRM_LEN 0x03 +#define SMP_RESP_NO_PHY 0x10 +#define SMP_RESP_NO_INDEX 0x11 +#define SMP_RESP_PHY_NO_SATA 0x12 +#define SMP_RESP_PHY_UNK_OP 0x13 +#define SMP_RESP_PHY_UNK_TESTF 0x14 +#define SMP_RESP_PHY_TEST_INPROG 0x15 +#define SMP_RESP_PHY_VACANT 0x16 + +/* SAM TMFs */ +#define TMF_ABORT_TASK 0x01 +#define TMF_ABORT_TASK_SET 0x02 +#define TMF_CLEAR_TASK_SET 0x04 +#define TMF_LU_RESET 0x08 +#define TMF_CLEAR_ACA 0x40 +#define TMF_QUERY_TASK 0x80 + +/* SAS TMF responses */ +#define TMF_RESP_FUNC_COMPLETE 0x00 +#define TMF_RESP_INVALID_FRAME 0x02 +#define TMF_RESP_FUNC_ESUPP 0x04 +#define TMF_RESP_FUNC_FAILED 0x05 +#define TMF_RESP_FUNC_SUCC 0x08 +#define TMF_RESP_NO_LUN 0x09 +#define TMF_RESP_OVERLAPPED_TAG 0x0A + +enum sas_oob_mode { + OOB_NOT_CONNECTED, + SATA_OOB_MODE, + SAS_OOB_MODE +}; + +/* See sas_discover.c if you plan on changing these. + */ +enum sas_dev_type { + NO_DEVICE = 0, /* protocol */ + SAS_END_DEV = 1, /* protocol */ + EDGE_DEV = 2, /* protocol */ + FANOUT_DEV = 3, /* protocol */ + SAS_HA = 4, + SATA_DEV = 5, + SATA_PM = 7, + SATA_PM_PORT= 8, +}; + +enum sas_protocol { + SAS_PROTOCOL_SATA = 0x01, + SAS_PROTOCOL_SMP = 0x02, + SAS_PROTOCOL_STP = 0x04, + SAS_PROTOCOL_SSP = 0x08, + SAS_PROTOCOL_ALL = 0x0E, +}; + +/* From the spec; local phys only */ +enum phy_func { + PHY_FUNC_NOP, + PHY_FUNC_LINK_RESET, /* Enables the phy */ + PHY_FUNC_HARD_RESET, + PHY_FUNC_DISABLE, + PHY_FUNC_CLEAR_ERROR_LOG = 5, + PHY_FUNC_CLEAR_AFFIL, + PHY_FUNC_TX_SATA_PS_SIGNAL, + PHY_FUNC_RELEASE_SPINUP_HOLD = 0x10, /* LOCAL PORT ONLY! */ + PHY_FUNC_SET_LINK_RATE, +}; + +/* SAS LLDD would need to report only _very_few_ of those, like BROADCAST. + * Most of those are here for completeness. + */ +enum sas_prim { + SAS_PRIM_AIP_NORMAL = 1, + SAS_PRIM_AIP_R0 = 2, + SAS_PRIM_AIP_R1 = 3, + SAS_PRIM_AIP_R2 = 4, + SAS_PRIM_AIP_WC = 5, + SAS_PRIM_AIP_WD = 6, + SAS_PRIM_AIP_WP = 7, + SAS_PRIM_AIP_RWP = 8, + + SAS_PRIM_BC_CH = 9, + SAS_PRIM_BC_RCH0 = 10, + SAS_PRIM_BC_RCH1 = 11, + SAS_PRIM_BC_R0 = 12, + SAS_PRIM_BC_R1 = 13, + SAS_PRIM_BC_R2 = 14, + SAS_PRIM_BC_R3 = 15, + SAS_PRIM_BC_R4 = 16, + + SAS_PRIM_NOTIFY_ENSP= 17, + SAS_PRIM_NOTIFY_R0 = 18, + SAS_PRIM_NOTIFY_R1 = 19, + SAS_PRIM_NOTIFY_R2 = 20, + + SAS_PRIM_CLOSE_CLAF = 21, + SAS_PRIM_CLOSE_NORM = 22, + SAS_PRIM_CLOSE_R0 = 23, + SAS_PRIM_CLOSE_R1 = 24, + + SAS_PRIM_OPEN_RTRY = 25, + SAS_PRIM_OPEN_RJCT = 26, + SAS_PRIM_OPEN_ACPT = 27, + + SAS_PRIM_DONE = 28, + SAS_PRIM_BREAK = 29, + + SATA_PRIM_DMAT = 33, + SATA_PRIM_PMNAK = 34, + SATA_PRIM_PMACK = 35, + SATA_PRIM_PMREQ_S = 36, + SATA_PRIM_PMREQ_P = 37, + SATA_SATA_R_ERR = 38, +}; + +enum sas_open_rej_reason { + /* Abandon open */ + SAS_OREJ_UNKNOWN = 0, + SAS_OREJ_BAD_DEST = 1, + SAS_OREJ_CONN_RATE = 2, + SAS_OREJ_EPROTO = 3, + SAS_OREJ_RESV_AB0 = 4, + SAS_OREJ_RESV_AB1 = 5, + SAS_OREJ_RESV_AB2 = 6, + SAS_OREJ_RESV_AB3 = 7, + SAS_OREJ_WRONG_DEST= 8, + SAS_OREJ_STP_NORES = 9, + + /* Retry open */ + SAS_OREJ_NO_DEST = 10, + SAS_OREJ_PATH_BLOCKED = 11, + SAS_OREJ_RSVD_CONT0 = 12, + SAS_OREJ_RSVD_CONT1 = 13, + SAS_OREJ_RSVD_INIT0 = 14, + SAS_OREJ_RSVD_INIT1 = 15, + SAS_OREJ_RSVD_STOP0 = 16, + SAS_OREJ_RSVD_STOP1 = 17, + SAS_OREJ_RSVD_RETRY = 18, +}; + +struct dev_to_host_fis { + u8 fis_type; /* 0x34 */ + u8 flags; + u8 status; + u8 error; + + u8 lbal; + union { u8 lbam; u8 byte_count_low; }; + union { u8 lbah; u8 byte_count_high; }; + u8 device; + + u8 lbal_exp; + u8 lbam_exp; + u8 lbah_exp; + u8 _r_a; + + union { u8 sector_count; u8 interrupt_reason; }; + u8 sector_count_exp; + u8 _r_b; + u8 _r_c; + + u32 _r_d; +} __attribute__ ((packed)); + +struct host_to_dev_fis { + u8 fis_type; /* 0x27 */ + u8 flags; + u8 command; + u8 features; + + u8 lbal; + union { u8 lbam; u8 byte_count_low; }; + union { u8 lbah; u8 byte_count_high; }; + u8 device; + + u8 lbal_exp; + u8 lbam_exp; + u8 lbah_exp; + u8 features_exp; + + union { u8 sector_count; u8 interrupt_reason; }; + u8 sector_count_exp; + u8 _r_a; + u8 control; + + u32 _r_b; +} __attribute__ ((packed)); + +/* Prefer to have code clarity over header file clarity. + */ +#ifdef __LITTLE_ENDIAN_BITFIELD +struct sas_identify_frame { + /* Byte 0 */ + u8 frame_type:4; + u8 dev_type:3; + u8 _un0:1; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un20:1; + u8 smp_iport:1; + u8 stp_iport:1; + u8 ssp_iport:1; + u8 _un247:4; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un30:1; + u8 smp_tport:1; + u8 stp_tport:1; + u8 ssp_tport:1; + u8 _un347:4; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; + + __be32 crc; +} __attribute__ ((packed)); + +struct ssp_frame_hdr { + u8 frame_type; + u8 hashed_dest_addr[HASHED_SAS_ADDR_SIZE]; + u8 _r_a; + u8 hashed_src_addr[HASHED_SAS_ADDR_SIZE]; + __be16 _r_b; + + u8 changing_data_ptr:1; + u8 retransmit:1; + u8 retry_data_frames:1; + u8 _r_c:5; + + u8 num_fill_bytes:2; + u8 _r_d:6; + + u32 _r_e; + __be16 tag; + __be16 tptt; + __be32 data_offs; +} __attribute__ ((packed)); + +struct ssp_response_iu { + u8 _r_a[10]; + + u8 datapres:2; + u8 _r_b:6; + + u8 status; + + u32 _r_c; + + __be32 sense_data_len; + __be32 response_data_len; + + u8 resp_data[0]; + u8 sense_data[0]; +} __attribute__ ((packed)); + +/* ---------- SMP ---------- */ + +struct report_general_resp { + __be16 change_count; + __be16 route_indexes; + u8 _r_a; + u8 num_phys; + + u8 conf_route_table:1; + u8 configuring:1; + u8 _r_b:6; + + u8 _r_c; + + u8 enclosure_logical_id[8]; + + u8 _r_d[12]; +} __attribute__ ((packed)); + +struct discover_resp { + u8 _r_a[5]; + + u8 phy_id; + __be16 _r_b; + + u8 _r_c:4; + u8 attached_dev_type:3; + u8 _r_d:1; + + u8 linkrate:4; + u8 _r_e:4; + + u8 attached_sata_host:1; + u8 iproto:3; + u8 _r_f:4; + + u8 attached_sata_dev:1; + u8 tproto:3; + u8 _r_g:3; + u8 attached_sata_ps:1; + + u8 sas_addr[8]; + u8 attached_sas_addr[8]; + u8 attached_phy_id; + + u8 _r_h[7]; + + u8 hmin_linkrate:4; + u8 pmin_linkrate:4; + u8 hmax_linkrate:4; + u8 pmax_linkrate:4; + + u8 change_count; + + u8 pptv:4; + u8 _r_i:3; + u8 virtual:1; + + u8 routing_attr:4; + u8 _r_j:4; + + u8 conn_type; + u8 conn_el_index; + u8 conn_phy_link; + + u8 _r_k[8]; +} __attribute__ ((packed)); + +struct report_phy_sata_resp { + u8 _r_a[5]; + + u8 phy_id; + u8 _r_b; + + u8 affil_valid:1; + u8 affil_supp:1; + u8 _r_c:6; + + u32 _r_d; + + u8 stp_sas_addr[8]; + + struct dev_to_host_fis fis; + + u32 _r_e; + + u8 affil_stp_ini_addr[8]; + + __be32 crc; +} __attribute__ ((packed)); + +struct smp_resp { + u8 frame_type; + u8 function; + u8 result; + u8 reserved; + union { + struct report_general_resp rg; + struct discover_resp disc; + struct report_phy_sata_resp rps; + }; +} __attribute__ ((packed)); + +#elif defined(__BIG_ENDIAN_BITFIELD) +struct sas_identify_frame { + /* Byte 0 */ + u8 _un0:1; + u8 dev_type:3; + u8 frame_type:4; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un247:4; + u8 ssp_iport:1; + u8 stp_iport:1; + u8 smp_iport:1; + u8 _un20:1; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un347:4; + u8 ssp_tport:1; + u8 stp_tport:1; + u8 smp_tport:1; + u8 _un30:1; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; + + __be32 crc; +} __attribute__ ((packed)); + +struct ssp_frame_hdr { + u8 frame_type; + u8 hashed_dest_addr[HASHED_SAS_ADDR_SIZE]; + u8 _r_a; + u8 hashed_src_addr[HASHED_SAS_ADDR_SIZE]; + __be16 _r_b; + + u8 _r_c:5; + u8 retry_data_frames:1; + u8 retransmit:1; + u8 changing_data_ptr:1; + + u8 _r_d:6; + u8 num_fill_bytes:2; + + u32 _r_e; + __be16 tag; + __be16 tptt; + __be32 data_offs; +} __attribute__ ((packed)); + +struct ssp_response_iu { + u8 _r_a[10]; + + u8 _r_b:6; + u8 datapres:2; + + u8 status; + + u32 _r_c; + + __be32 sense_data_len; + __be32 response_data_len; + + u8 resp_data[0]; + u8 sense_data[0]; +} __attribute__ ((packed)); + +/* ---------- SMP ---------- */ + +struct report_general_resp { + __be16 change_count; + __be16 route_indexes; + u8 _r_a; + u8 num_phys; + + u8 _r_b:6; + u8 configuring:1; + u8 conf_route_table:1; + + u8 _r_c; + + u8 enclosure_logical_id[8]; + + u8 _r_d[12]; +} __attribute__ ((packed)); + +struct discover_resp { + u8 _r_a[5]; + + u8 phy_id; + __be16 _r_b; + + u8 _r_d:1; + u8 attached_dev_type:3; + u8 _r_c:4; + + u8 _r_e:4; + u8 linkrate:4; + + u8 _r_f:4; + u8 iproto:3; + u8 attached_sata_host:1; + + u8 attached_sata_ps:1; + u8 _r_g:3; + u8 tproto:3; + u8 attached_sata_dev:1; + + u8 sas_addr[8]; + u8 attached_sas_addr[8]; + u8 attached_phy_id; + + u8 _r_h[7]; + + u8 pmin_linkrate:4; + u8 hmin_linkrate:4; + u8 pmax_linkrate:4; + u8 hmax_linkrate:4; + + u8 change_count; + + u8 virtual:1; + u8 _r_i:3; + u8 pptv:4; + + u8 _r_j:4; + u8 routing_attr:4; + + u8 conn_type; + u8 conn_el_index; + u8 conn_phy_link; + + u8 _r_k[8]; +} __attribute__ ((packed)); + +struct report_phy_sata_resp { + u8 _r_a[5]; + + u8 phy_id; + u8 _r_b; + + u8 _r_c:6; + u8 affil_supp:1; + u8 affil_valid:1; + + u32 _r_d; + + u8 stp_sas_addr[8]; + + struct dev_to_host_fis fis; + + u32 _r_e; + + u8 affil_stp_ini_addr[8]; + + __be32 crc; +} __attribute__ ((packed)); + +struct smp_resp { + u8 frame_type; + u8 function; + u8 result; + u8 reserved; + union { + struct report_general_resp rg; + struct discover_resp disc; + struct report_phy_sata_resp rps; + }; +} __attribute__ ((packed)); + +#else +#error "Bitfield order not defined!" +#endif + +#endif /* _SAS_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/sas_ata.h b/libdde_linux26/contrib/include/scsi/sas_ata.h new file mode 100644 index 00000000..c583193a --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/sas_ata.h @@ -0,0 +1,60 @@ +/* + * Support for SATA devices on Serial Attached SCSI (SAS) controllers + * + * Copyright (C) 2006 IBM Corporation + * + * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +#ifndef _SAS_ATA_H_ +#define _SAS_ATA_H_ + +#include <linux/libata.h> +#include <scsi/libsas.h> + +#ifdef CONFIG_SCSI_SAS_ATA + +static inline int dev_is_sata(struct domain_device *dev) +{ + return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA); +} + +int sas_ata_init_host_and_port(struct domain_device *found_dev, + struct scsi_target *starget); + +void sas_ata_task_abort(struct sas_task *task); + +#else + + +static inline int dev_is_sata(struct domain_device *dev) +{ + return 0; +} +static inline int sas_ata_init_host_and_port(struct domain_device *found_dev, + struct scsi_target *starget) +{ + return 0; +} +static inline void sas_ata_task_abort(struct sas_task *task) +{ +} +#endif + +#endif /* _SAS_ATA_H_ */ diff --git a/libdde_linux26/contrib/include/scsi/scsi.h b/libdde_linux26/contrib/include/scsi/scsi.h new file mode 100644 index 00000000..a1091657 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi.h @@ -0,0 +1,536 @@ +/* + * This header file contains public constants and structures used by + * the scsi code for linux. + * + * For documentation on the OPCODES, MESSAGES, and SENSE values, + * please consult the SCSI standard. + */ +#ifndef _SCSI_SCSI_H +#define _SCSI_SCSI_H + +#include <linux/types.h> +#include <scsi/scsi_cmnd.h> + +/* + * The maximum number of SG segments that we will put inside a + * scatterlist (unless chaining is used). Should ideally fit inside a + * single page, to avoid a higher order allocation. We could define this + * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The + * minimum value is 32 + */ +#define SCSI_MAX_SG_SEGMENTS 128 + +/* + * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit + * is totally arbitrary, a setting of 2048 will get you at least 8mb ios. + */ +#ifdef ARCH_HAS_SG_CHAIN +#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048 +#else +#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS +#endif + +/* + * Special value for scanning to specify scanning or rescanning of all + * possible channels, (target) ids, or luns on a given shost. + */ +#define SCAN_WILD_CARD ~0 + +/* + * SCSI opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define INITIALIZE_ELEMENT_STATUS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define POSITION_TO_ELEMENT 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define READ_TOC 0x43 +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 +#define MODE_SELECT_10 0x55 +#define RESERVE_10 0x56 +#define RELEASE_10 0x57 +#define MODE_SENSE_10 0x5a +#define PERSISTENT_RESERVE_IN 0x5e +#define PERSISTENT_RESERVE_OUT 0x5f +#define VARIABLE_LENGTH_CMD 0x7f +#define REPORT_LUNS 0xa0 +#define MAINTENANCE_IN 0xa3 +#define MAINTENANCE_OUT 0xa4 +#define MOVE_MEDIUM 0xa5 +#define EXCHANGE_MEDIUM 0xa6 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define WRITE_VERIFY_12 0xae +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define READ_ELEMENT_STATUS 0xb8 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea +#define READ_16 0x88 +#define WRITE_16 0x8a +#define VERIFY_16 0x8f +#define SERVICE_ACTION_IN 0x9e +/* values for service action in */ +#define SAI_READ_CAPACITY_16 0x10 +/* values for maintenance in */ +#define MI_REPORT_TARGET_PGS 0x0a +/* values for maintenance out */ +#define MO_SET_TARGET_PGS 0x0a + +/* Values for T10/04-262r7 */ +#define ATA_16 0x85 /* 16-byte pass-thru */ +#define ATA_12 0xa1 /* 12-byte pass-thru */ + +/* + * SCSI command lengths + */ + +#define SCSI_MAX_VARLEN_CDB_SIZE 260 + +/* defined in T10 SCSI Primary Commands-2 (SPC2) */ +struct scsi_varlen_cdb_hdr { + u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ + u8 control; + u8 misc[5]; + u8 additional_cdb_length; /* total cdb length - 8 */ + __be16 service_action; + /* service specific data follows */ +}; + +static inline unsigned +scsi_varlen_cdb_length(const void *hdr) +{ + return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; +} + +extern const unsigned char scsi_command_size_tbl[8]; +#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] + +static inline unsigned +scsi_command_size(const unsigned char *cmnd) +{ + return (cmnd[0] == VARIABLE_LENGTH_CMD) ? + scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); +} + +/* + * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft + * T10/1561-D Revision 4 Draft dated 7th November 2002. + */ +#define SAM_STAT_GOOD 0x00 +#define SAM_STAT_CHECK_CONDITION 0x02 +#define SAM_STAT_CONDITION_MET 0x04 +#define SAM_STAT_BUSY 0x08 +#define SAM_STAT_INTERMEDIATE 0x10 +#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 +#define SAM_STAT_RESERVATION_CONFLICT 0x18 +#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ +#define SAM_STAT_TASK_SET_FULL 0x28 +#define SAM_STAT_ACA_ACTIVE 0x30 +#define SAM_STAT_TASK_ABORTED 0x40 + +/** scsi_status_is_good - check the status return. + * + * @status: the status passed up from the driver (including host and + * driver components) + * + * This returns true for known good conditions that may be treated as + * command completed normally + */ +static inline int scsi_status_is_good(int status) +{ + /* + * FIXME: bit0 is listed as reserved in SCSI-2, but is + * significant in SCSI-3. For now, we follow the SCSI-2 + * behaviour and ignore reserved bits. + */ + status &= 0xfe; + return ((status == SAM_STAT_GOOD) || + (status == SAM_STAT_INTERMEDIATE) || + (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || + /* FIXME: this is obsolete in SAM-3 */ + (status == SAM_STAT_COMMAND_TERMINATED)); +} + +/* + * Status codes. These are deprecated as they are shifted 1 bit right + * from those found in the SCSI standards. This causes confusion for + * applications that are ported to several OSes. Prefer SAM Status codes + * above. + */ + +#define GOOD 0x00 +#define CHECK_CONDITION 0x01 +#define CONDITION_GOOD 0x02 +#define BUSY 0x04 +#define INTERMEDIATE_GOOD 0x08 +#define INTERMEDIATE_C_GOOD 0x0a +#define RESERVATION_CONFLICT 0x0c +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 +#define ACA_ACTIVE 0x18 +#define TASK_ABORTED 0x20 + +#define STATUS_MASK 0xfe + +/* + * SENSE KEYS + */ + +#define NO_SENSE 0x00 +#define RECOVERED_ERROR 0x01 +#define NOT_READY 0x02 +#define MEDIUM_ERROR 0x03 +#define HARDWARE_ERROR 0x04 +#define ILLEGAL_REQUEST 0x05 +#define UNIT_ATTENTION 0x06 +#define DATA_PROTECT 0x07 +#define BLANK_CHECK 0x08 +#define COPY_ABORTED 0x0a +#define ABORTED_COMMAND 0x0b +#define VOLUME_OVERFLOW 0x0d +#define MISCOMPARE 0x0e + + +/* + * DEVICE TYPES + * Please keep them in 0x%02x format for $MODALIAS to work + */ + +#define TYPE_DISK 0x00 +#define TYPE_TAPE 0x01 +#define TYPE_PRINTER 0x02 +#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ +#define TYPE_WORM 0x04 /* Treated as ROM by our system */ +#define TYPE_ROM 0x05 +#define TYPE_SCANNER 0x06 +#define TYPE_MOD 0x07 /* Magneto-optical disk - + * - treated as TYPE_DISK */ +#define TYPE_MEDIUM_CHANGER 0x08 +#define TYPE_COMM 0x09 /* Communications device */ +#define TYPE_RAID 0x0c +#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define TYPE_RBC 0x0e +#define TYPE_NO_LUN 0x7f + +/* SCSI protocols; these are taken from SPC-3 section 7.5 */ +enum scsi_protocol { + SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ + SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ + SCSI_PROTOCOL_SSA = 2, /* Serial Storage Architecture - Obsolete */ + SCSI_PROTOCOL_SBP = 3, /* firewire */ + SCSI_PROTOCOL_SRP = 4, /* Infiniband RDMA */ + SCSI_PROTOCOL_ISCSI = 5, + SCSI_PROTOCOL_SAS = 6, + SCSI_PROTOCOL_ADT = 7, /* Media Changers */ + SCSI_PROTOCOL_ATA = 8, + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ +}; + +/* Returns a human-readable name for the device */ +extern const char * scsi_device_type(unsigned type); + +/* + * standard mode-select header prepended to all mode-select commands + */ + +struct ccs_modesel_head { + __u8 _r1; /* reserved */ + __u8 medium; /* device-specific medium type */ + __u8 _r2; /* reserved */ + __u8 block_desc_length; /* block descriptor length */ + __u8 density; /* device-specific density code */ + __u8 number_blocks_hi; /* number of blocks in this block desc */ + __u8 number_blocks_med; + __u8 number_blocks_lo; + __u8 _r3; + __u8 block_length_hi; /* block length for blocks in this desc */ + __u8 block_length_med; + __u8 block_length_lo; +}; + +/* + * ScsiLun: 8 byte LUN. + */ +struct scsi_lun { + __u8 scsi_lun[8]; +}; + +/* + * The Well Known LUNS (SAM-3) in our int representation of a LUN + */ +#define SCSI_W_LUN_BASE 0xc100 +#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1) +#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2) +#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3) + +static inline int scsi_is_wlun(unsigned int lun) +{ + return (lun & 0xff00) == SCSI_W_LUN_BASE; +} + + +/* + * MESSAGE CODES + */ + +#define COMMAND_COMPLETE 0x00 +#define EXTENDED_MESSAGE 0x01 +#define EXTENDED_MODIFY_DATA_POINTER 0x00 +#define EXTENDED_SDTR 0x01 +#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ +#define EXTENDED_WDTR 0x03 +#define EXTENDED_PPR 0x04 +#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05 +#define SAVE_POINTERS 0x02 +#define RESTORE_POINTERS 0x03 +#define DISCONNECT 0x04 +#define INITIATOR_ERROR 0x05 +#define ABORT_TASK_SET 0x06 +#define MESSAGE_REJECT 0x07 +#define NOP 0x08 +#define MSG_PARITY_ERROR 0x09 +#define LINKED_CMD_COMPLETE 0x0a +#define LINKED_FLG_CMD_COMPLETE 0x0b +#define TARGET_RESET 0x0c +#define ABORT_TASK 0x0d +#define CLEAR_TASK_SET 0x0e +#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ +#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ +#define CLEAR_ACA 0x16 +#define LOGICAL_UNIT_RESET 0x17 +#define SIMPLE_QUEUE_TAG 0x20 +#define HEAD_OF_QUEUE_TAG 0x21 +#define ORDERED_QUEUE_TAG 0x22 +#define IGNORE_WIDE_RESIDUE 0x23 +#define ACA 0x24 +#define QAS_REQUEST 0x55 + +/* Old SCSI2 names, don't use in new code */ +#define BUS_DEVICE_RESET TARGET_RESET +#define ABORT ABORT_TASK_SET + +/* + * Host byte codes + */ + +#define DID_OK 0x00 /* NO error */ +#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ +#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ +#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ +#define DID_BAD_TARGET 0x04 /* BAD target. */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody. */ +#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */ +#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */ +#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */ +#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also + * without decrementing the retry count */ +#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution + * and the driver blocked the port to + * recover the link. Transport class will + * retry or fail IO */ +#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */ +#define DRIVER_OK 0x00 /* Driver status */ + +/* + * These indicate the error that occurred, and what is available. + */ + +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 + +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 + +#define SUGGEST_RETRY 0x10 +#define SUGGEST_ABORT 0x20 +#define SUGGEST_REMAP 0x30 +#define SUGGEST_DIE 0x40 +#define SUGGEST_SENSE 0x80 +#define SUGGEST_IS_OK 0xff + +#define DRIVER_MASK 0x0f +#define SUGGEST_MASK 0xf0 + +/* + * Internal return values. + */ + +#define NEEDS_RETRY 0x2001 +#define SUCCESS 0x2002 +#define FAILED 0x2003 +#define QUEUED 0x2004 +#define SOFT_ERROR 0x2005 +#define ADD_TO_MLQUEUE 0x2006 +#define TIMEOUT_ERROR 0x2007 +#define SCSI_RETURN_NOT_HANDLED 0x2008 + +/* + * Midlevel queue return values. + */ +#define SCSI_MLQUEUE_HOST_BUSY 0x1055 +#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 +#define SCSI_MLQUEUE_EH_RETRY 0x1057 +#define SCSI_MLQUEUE_TARGET_BUSY 0x1058 + +/* + * Use these to separate status msg and our bytes + * + * These are set by: + * + * status byte = set from target device + * msg_byte = return status from host adapter itself. + * host_byte = set by low-level driver to indicate status. + * driver_byte = set by mid-level. + */ +#define status_byte(result) (((result) >> 1) & 0x7f) +#define msg_byte(result) (((result) >> 8) & 0xff) +#define host_byte(result) (((result) >> 16) & 0xff) +#define driver_byte(result) (((result) >> 24) & 0xff) +#define suggestion(result) (driver_byte(result) & SUGGEST_MASK) + +static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 8; +} + +static inline void set_host_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 16; +} + +static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 24; +} + + +#define sense_class(sense) (((sense) >> 4) & 0x7) +#define sense_error(sense) ((sense) & 0xf) +#define sense_valid(sense) ((sense) & 0x80); + +/* + * default timeouts +*/ +#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ) +#define START_STOP_TIMEOUT (60 * HZ) +#define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ) +#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ) +#define READ_DEFECT_DATA_TIMEOUT (60 * HZ ) + + +#define IDENTIFY_BASE 0x80 +#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\ + ((can_disconnect) ? 0x40 : 0) |\ + ((lun) & 0x07)) + +/* + * struct scsi_device::scsi_level values. For SCSI devices other than those + * prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1) + * where "resp" is a byte array of the response to an INQUIRY. The scsi_level + * variable is visible to the user via sysfs. + */ + +#define SCSI_UNKNOWN 0 +#define SCSI_1 1 +#define SCSI_1_CCS 2 +#define SCSI_2 3 +#define SCSI_3 4 /* SPC */ +#define SCSI_SPC_2 5 +#define SCSI_SPC_3 6 + +/* + * INQ PERIPHERAL QUALIFIERS + */ +#define SCSI_INQ_PQ_CON 0x00 +#define SCSI_INQ_PQ_NOT_CON 0x01 +#define SCSI_INQ_PQ_NOT_CAP 0x03 + + +/* + * Here are some scsi specific ioctl commands which are sometimes useful. + * + * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395 + */ + +/* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */ +#define SCSI_IOCTL_GET_IDLUN 0x5382 + +/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */ + +/* Used to obtain the host number of a device. */ +#define SCSI_IOCTL_PROBE_HOST 0x5385 + +/* Used to obtain the bus number for a device */ +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 + +/* Used to obtain the PCI location of a device */ +#define SCSI_IOCTL_GET_PCI 0x5387 + +/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */ +static inline __u32 scsi_to_u32(__u8 *ptr) +{ + return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; +} + +#endif /* _SCSI_SCSI_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_cmnd.h b/libdde_linux26/contrib/include/scsi/scsi_cmnd.h new file mode 100644 index 00000000..855bf959 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_cmnd.h @@ -0,0 +1,294 @@ +#ifndef _SCSI_SCSI_CMND_H +#define _SCSI_SCSI_CMND_H + +#include <linux/dma-mapping.h> +#include <linux/blkdev.h> +#include <linux/list.h> +#include <linux/types.h> +#include <linux/timer.h> +#include <linux/scatterlist.h> + +struct Scsi_Host; +struct scsi_device; + +/* + * MAX_COMMAND_SIZE is: + * The longest fixed-length SCSI CDB as per the SCSI standard. + * fixed-length means: commands that their size can be determined + * by their opcode and the CDB does not carry a length specifier, (unlike + * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly + * true and the SCSI standard also defines extended commands and + * vendor specific commands that can be bigger than 16 bytes. The kernel + * will support these using the same infrastructure used for VARLEN CDB's. + * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml + * supports without specifying a cmd_len by ULD's + */ +#define MAX_COMMAND_SIZE 16 +#if (MAX_COMMAND_SIZE > BLK_MAX_CDB) +# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB +#endif + +struct scsi_data_buffer { + struct sg_table table; + unsigned length; + int resid; +}; + +/* embedded in scsi_cmnd */ +struct scsi_pointer { + char *ptr; /* data pointer */ + int this_residual; /* left in this buffer */ + struct scatterlist *buffer; /* which buffer */ + int buffers_residual; /* how many buffers left */ + + dma_addr_t dma_handle; + + volatile int Status; + volatile int Message; + volatile int have_data_in; + volatile int sent_command; + volatile int phase; +}; + +struct scsi_cmnd { + struct scsi_device *device; + struct list_head list; /* scsi_cmnd participates in queue lists */ + struct list_head eh_entry; /* entry for the host eh_cmd_q */ + int eh_eflags; /* Used by error handlr */ + + /* + * A SCSI Command is assigned a nonzero serial_number before passed + * to the driver's queue command function. The serial_number is + * cleared when scsi_done is entered indicating that the command + * has been completed. It is a bug for LLDDs to use this number + * for purposes other than printk (and even that is only useful + * for debugging). + */ + unsigned long serial_number; + + /* + * This is set to jiffies as it was when the command was first + * allocated. It is used to time how long the command has + * been outstanding + */ + unsigned long jiffies_at_alloc; + + int retries; + int allowed; + + unsigned char prot_op; + unsigned char prot_type; + + unsigned short cmd_len; + enum dma_data_direction sc_data_direction; + + /* These elements define the operation we are about to perform */ + unsigned char *cmnd; + + + /* These elements define the operation we ultimately want to perform */ + struct scsi_data_buffer sdb; + struct scsi_data_buffer *prot_sdb; + + unsigned underflow; /* Return error if less than + this amount is transferred */ + + unsigned transfersize; /* How much we are guaranteed to + transfer with each SCSI transfer + (ie, between disconnect / + reconnects. Probably == sector + size */ + + struct request *request; /* The command we are + working on */ + +#define SCSI_SENSE_BUFFERSIZE 96 + unsigned char *sense_buffer; + /* obtained by REQUEST SENSE when + * CHECK CONDITION is received on original + * command (auto-sense) */ + + /* Low-level done function - can be used by low-level driver to point + * to completion function. Not used by mid/upper level code. */ + void (*scsi_done) (struct scsi_cmnd *); + + /* + * The following fields can be written to by the host specific code. + * Everything else should be left alone. + */ + struct scsi_pointer SCp; /* Scratchpad used by some host adapters */ + + unsigned char *host_scribble; /* The host adapter is allowed to + * call scsi_malloc and get some memory + * and hang it here. The host adapter + * is also expected to call scsi_free + * to release this memory. (The memory + * obtained by scsi_malloc is guaranteed + * to be at an address < 16Mb). */ + + int result; /* Status code from lower level driver */ + + unsigned char tag; /* SCSI-II queued command tag */ +}; + +extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); +extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); +extern void scsi_put_command(struct scsi_cmnd *); +extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, + struct device *); +extern void scsi_finish_command(struct scsi_cmnd *cmd); + +extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, + size_t *offset, size_t *len); +extern void scsi_kunmap_atomic_sg(void *virt); + +extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask); +extern void scsi_release_buffers(struct scsi_cmnd *cmd); + +extern int scsi_dma_map(struct scsi_cmnd *cmd); +extern void scsi_dma_unmap(struct scsi_cmnd *cmd); + +struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); +void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); + +static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.nents; +} + +static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.sgl; +} + +static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd) +{ + return cmd->sdb.length; +} + +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->sdb.resid = resid; +} + +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->sdb.resid; +} + +#define scsi_for_each_sg(cmd, sg, nseg, __i) \ + for_each_sg(scsi_sglist(cmd), sg, nseg, __i) + +static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd) +{ + return blk_bidi_rq(cmd->request) && + (cmd->request->next_rq->special != NULL); +} + +static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd) +{ + return scsi_bidi_cmnd(cmd) ? + cmd->request->next_rq->special : &cmd->sdb; +} + +static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd) +{ + return &cmd->sdb; +} + +static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, + void *buf, int buflen) +{ + return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); +} + +static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, + void *buf, int buflen) +{ + return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, buflen); +} + +/* + * The operations below are hints that tell the controller driver how + * to handle I/Os with DIF or similar types of protection information. + */ +enum scsi_prot_operations { + /* Normal I/O */ + SCSI_PROT_NORMAL = 0, + + /* OS-HBA: Protected, HBA-Target: Unprotected */ + SCSI_PROT_READ_INSERT, + SCSI_PROT_WRITE_STRIP, + + /* OS-HBA: Unprotected, HBA-Target: Protected */ + SCSI_PROT_READ_STRIP, + SCSI_PROT_WRITE_INSERT, + + /* OS-HBA: Protected, HBA-Target: Protected */ + SCSI_PROT_READ_PASS, + SCSI_PROT_WRITE_PASS, + + /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ + SCSI_PROT_READ_CONVERT, + SCSI_PROT_WRITE_CONVERT, +}; + +static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) +{ + scmd->prot_op = op; +} + +static inline unsigned char scsi_get_prot_op(struct scsi_cmnd *scmd) +{ + return scmd->prot_op; +} + +/* + * The controller usually does not know anything about the target it + * is communicating with. However, when DIX is enabled the controller + * must be know target type so it can verify the protection + * information passed along with the I/O. + */ +enum scsi_prot_target_type { + SCSI_PROT_DIF_TYPE0 = 0, + SCSI_PROT_DIF_TYPE1, + SCSI_PROT_DIF_TYPE2, + SCSI_PROT_DIF_TYPE3, +}; + +static inline void scsi_set_prot_type(struct scsi_cmnd *scmd, unsigned char type) +{ + scmd->prot_type = type; +} + +static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) +{ + return scmd->prot_type; +} + +static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) +{ + return scmd->request->sector; +} + +static inline unsigned scsi_prot_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb ? cmd->prot_sdb->table.nents : 0; +} + +static inline struct scatterlist *scsi_prot_sglist(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb ? cmd->prot_sdb->table.sgl : NULL; +} + +static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) +{ + return cmd->prot_sdb; +} + +#define scsi_for_each_prot_sg(cmd, sg, nseg, __i) \ + for_each_sg(scsi_prot_sglist(cmd), sg, nseg, __i) + +#endif /* _SCSI_SCSI_CMND_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_dbg.h b/libdde_linux26/contrib/include/scsi/scsi_dbg.h new file mode 100644 index 00000000..e89844cc --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_dbg.h @@ -0,0 +1,24 @@ +#ifndef _SCSI_SCSI_DBG_H +#define _SCSI_SCSI_DBG_H + +struct scsi_cmnd; +struct scsi_sense_hdr; + +extern void scsi_print_command(struct scsi_cmnd *); +extern void __scsi_print_command(unsigned char *); +extern void scsi_show_extd_sense(unsigned char, unsigned char); +extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); +extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); +extern void scsi_cmd_print_sense_hdr(struct scsi_cmnd *, const char *, + struct scsi_sense_hdr *); +extern void scsi_print_sense(char *, struct scsi_cmnd *); +extern void __scsi_print_sense(const char *name, + const unsigned char *sense_buffer, + int sense_len); +extern void scsi_show_result(int); +extern void scsi_print_result(struct scsi_cmnd *); +extern void scsi_print_status(unsigned char); +extern const char *scsi_sense_key_string(unsigned char); +extern const char *scsi_extd_sense_format(unsigned char, unsigned char); + +#endif /* _SCSI_SCSI_DBG_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_device.h b/libdde_linux26/contrib/include/scsi/scsi_device.h new file mode 100644 index 00000000..01a4c58f --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_device.h @@ -0,0 +1,461 @@ +#ifndef _SCSI_SCSI_DEVICE_H +#define _SCSI_SCSI_DEVICE_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/workqueue.h> +#include <linux/blkdev.h> +#include <scsi/scsi.h> +#include <asm/atomic.h> + +struct request_queue; +struct scsi_cmnd; +struct scsi_lun; +struct scsi_sense_hdr; + +struct scsi_mode_data { + __u32 length; + __u16 block_descriptor_length; + __u8 medium_type; + __u8 device_specific; + __u8 header_length; + __u8 longlba:1; +}; + +/* + * sdev state: If you alter this, you also need to alter scsi_sysfs.c + * (for the ascii descriptions) and the state model enforcer: + * scsi_lib:scsi_device_set_state(). + */ +enum scsi_device_state { + SDEV_CREATED = 1, /* device created but not added to sysfs + * Only internal commands allowed (for inq) */ + SDEV_RUNNING, /* device properly configured + * All commands allowed */ + SDEV_CANCEL, /* beginning to delete device + * Only error handler commands allowed */ + SDEV_DEL, /* device deleted + * no commands allowed */ + SDEV_QUIESCE, /* Device quiescent. No block commands + * will be accepted, only specials (which + * originate in the mid-layer) */ + SDEV_OFFLINE, /* Device offlined (by error handling or + * user request */ + SDEV_BLOCK, /* Device blocked by scsi lld. No + * scsi commands from user or midlayer + * should be issued to the scsi + * lld. */ + SDEV_CREATED_BLOCK, /* same as above but for created devices */ +}; + +enum scsi_device_event { + SDEV_EVT_MEDIA_CHANGE = 1, /* media has changed */ + + SDEV_EVT_LAST = SDEV_EVT_MEDIA_CHANGE, + SDEV_EVT_MAXBITS = SDEV_EVT_LAST + 1 +}; + +struct scsi_event { + enum scsi_device_event evt_type; + struct list_head node; + + /* put union of data structures, for non-simple event types, + * here + */ +}; + +struct scsi_device { + struct Scsi_Host *host; + struct request_queue *request_queue; + + /* the next two are protected by the host->host_lock */ + struct list_head siblings; /* list of all devices on this host */ + struct list_head same_target_siblings; /* just the devices sharing same target id */ + + /* this is now protected by the request_queue->queue_lock */ + unsigned int device_busy; /* commands actually active on + * low-level. protected by queue_lock. */ + spinlock_t list_lock; + struct list_head cmd_list; /* queue of in use SCSI Command structures */ + struct list_head starved_entry; + struct scsi_cmnd *current_cmnd; /* currently active command */ + unsigned short queue_depth; /* How deep of a queue we want */ + unsigned short last_queue_full_depth; /* These two are used by */ + unsigned short last_queue_full_count; /* scsi_track_queue_full() */ + unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same + jiffie count on our counter, they + could all be from the same event. */ + + unsigned int id, lun, channel; + + unsigned int manufacturer; /* Manufacturer of device, for using + * vendor-specific cmd's */ + unsigned sector_size; /* size in bytes */ + + void *hostdata; /* available to low-level driver */ + char type; + char scsi_level; + char inq_periph_qual; /* PQ from INQUIRY data */ + unsigned char inquiry_len; /* valid bytes in 'inquiry' */ + unsigned char * inquiry; /* INQUIRY response data */ + const char * vendor; /* [back_compat] point into 'inquiry' ... */ + const char * model; /* ... after scan; point to static string */ + const char * rev; /* ... "nullnullnullnull" before scan */ + unsigned char current_tag; /* current tag */ + struct scsi_target *sdev_target; /* used only for single_lun */ + + unsigned int sdev_bflags; /* black/white flags as also found in + * scsi_devinfo.[hc]. For now used only to + * pass settings from slave_alloc to scsi + * core. */ + unsigned writeable:1; + unsigned removable:1; + unsigned changed:1; /* Data invalid due to media change */ + unsigned busy:1; /* Used to prevent races */ + unsigned lockable:1; /* Able to prevent media removal */ + unsigned locked:1; /* Media removal disabled */ + unsigned borken:1; /* Tell the Seagate driver to be + * painfully slow on this device */ + unsigned disconnect:1; /* can disconnect */ + unsigned soft_reset:1; /* Uses soft reset option */ + unsigned sdtr:1; /* Device supports SDTR messages */ + unsigned wdtr:1; /* Device supports WDTR messages */ + unsigned ppr:1; /* Device supports PPR messages */ + unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */ + unsigned simple_tags:1; /* simple queue tag messages are enabled */ + unsigned ordered_tags:1;/* ordered queue tag messages are enabled */ + unsigned was_reset:1; /* There was a bus reset on the bus for + * this device */ + unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN + * because we did a bus reset. */ + unsigned use_10_for_rw:1; /* first try 10-byte read / write */ + unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ + unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ + unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ + unsigned no_start_on_add:1; /* do not issue start on add */ + unsigned allow_restart:1; /* issue START_UNIT in error handler */ + unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ + unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ + unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ + unsigned select_no_atn:1; + unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ + unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ + unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ + unsigned last_sector_bug:1; /* do not use multisector accesses on + SD_LAST_BUGGY_SECTORS */ + + DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ + struct list_head event_list; /* asserted events */ + struct work_struct event_work; + + unsigned int device_blocked; /* Device returned QUEUE_FULL. */ + + unsigned int max_device_blocked; /* what device_blocked counts down from */ +#define SCSI_DEFAULT_DEVICE_BLOCKED 3 + + atomic_t iorequest_cnt; + atomic_t iodone_cnt; + atomic_t ioerr_cnt; + + struct device sdev_gendev, + sdev_dev; + + struct execute_work ew; /* used to get process context on put */ + + struct scsi_dh_data *scsi_dh_data; + enum scsi_device_state sdev_state; + unsigned long sdev_data[0]; +} __attribute__((aligned(sizeof(unsigned long)))); + +struct scsi_dh_devlist { + char *vendor; + char *model; +}; + +struct scsi_device_handler { + /* Used by the infrastructure */ + struct list_head list; /* list of scsi_device_handlers */ + + /* Filled by the hardware handler */ + struct module *module; + const char *name; + const struct scsi_dh_devlist *devlist; + int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); + int (*attach)(struct scsi_device *); + void (*detach)(struct scsi_device *); + int (*activate)(struct scsi_device *); + int (*prep_fn)(struct scsi_device *, struct request *); +}; + +struct scsi_dh_data { + struct scsi_device_handler *scsi_dh; + char buf[0]; +}; + +#define to_scsi_device(d) \ + container_of(d, struct scsi_device, sdev_gendev) +#define class_to_sdev(d) \ + container_of(d, struct scsi_device, sdev_dev) +#define transport_class_to_sdev(class_dev) \ + to_scsi_device(class_dev->parent) + +#define sdev_printk(prefix, sdev, fmt, a...) \ + dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) + +#define scmd_printk(prefix, scmd, fmt, a...) \ + (scmd)->request->rq_disk ? \ + sdev_printk(prefix, (scmd)->device, "[%s] " fmt, \ + (scmd)->request->rq_disk->disk_name, ##a) : \ + sdev_printk(prefix, (scmd)->device, fmt, ##a) + +enum scsi_target_state { + STARGET_CREATED = 1, + STARGET_RUNNING, + STARGET_DEL, +}; + +/* + * scsi_target: representation of a scsi target, for now, this is only + * used for single_lun devices. If no one has active IO to the target, + * starget_sdev_user is NULL, else it points to the active sdev. + */ +struct scsi_target { + struct scsi_device *starget_sdev_user; + struct list_head siblings; + struct list_head devices; + struct device dev; + unsigned int reap_ref; /* protected by the host lock */ + unsigned int channel; + unsigned int id; /* target id ... replace + * scsi_device.id eventually */ + unsigned int create:1; /* signal that it needs to be added */ + unsigned int single_lun:1; /* Indicates we should only + * allow I/O to one of the luns + * for the device at a time. */ + unsigned int pdt_1f_for_no_lun; /* PDT = 0x1f */ + /* means no lun present */ + /* commands actually active on LLD. protected by host lock. */ + unsigned int target_busy; + /* + * LLDs should set this in the slave_alloc host template callout. + * If set to zero then there is not limit. + */ + unsigned int can_queue; + unsigned int target_blocked; + unsigned int max_target_blocked; +#define SCSI_DEFAULT_TARGET_BLOCKED 3 + + char scsi_level; + struct execute_work ew; + enum scsi_target_state state; + void *hostdata; /* available to low-level driver */ + unsigned long starget_data[0]; /* for the transport */ + /* starget_data must be the last element!!!! */ +} __attribute__((aligned(sizeof(unsigned long)))); + +#define to_scsi_target(d) container_of(d, struct scsi_target, dev) +static inline struct scsi_target *scsi_target(struct scsi_device *sdev) +{ + return to_scsi_target(sdev->sdev_gendev.parent); +} +#define transport_class_to_starget(class_dev) \ + to_scsi_target(class_dev->parent) + +#define starget_printk(prefix, starget, fmt, a...) \ + dev_printk(prefix, &(starget)->dev, fmt, ##a) + +extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, + uint, uint, uint, void *hostdata); +extern int scsi_add_device(struct Scsi_Host *host, uint channel, + uint target, uint lun); +extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh); +extern void scsi_remove_device(struct scsi_device *); +extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); + +extern int scsi_device_get(struct scsi_device *); +extern void scsi_device_put(struct scsi_device *); +extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, + uint, uint, uint); +extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *, + uint, uint, uint); +extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *, + uint); +extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *, + uint); +extern void starget_for_each_device(struct scsi_target *, void *, + void (*fn)(struct scsi_device *, void *)); +extern void __starget_for_each_device(struct scsi_target *, void *, + void (*fn)(struct scsi_device *, + void *)); + +/* only exposed to implement shost_for_each_device */ +extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, + struct scsi_device *); + +/** + * shost_for_each_device - iterate over all devices of a host + * @sdev: the &struct scsi_device to use as a cursor + * @shost: the &struct scsi_host to iterate over + * + * Iterator that returns each device attached to @shost. This loop + * takes a reference on each device and releases it at the end. If + * you break out of the loop, you must call scsi_device_put(sdev). + */ +#define shost_for_each_device(sdev, shost) \ + for ((sdev) = __scsi_iterate_devices((shost), NULL); \ + (sdev); \ + (sdev) = __scsi_iterate_devices((shost), (sdev))) + +/** + * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) + * @sdev: the &struct scsi_device to use as a cursor + * @shost: the &struct scsi_host to iterate over + * + * Iterator that returns each device attached to @shost. It does _not_ + * take a reference on the scsi_device, so the whole loop must be + * protected by shost->host_lock. + * + * Note: The only reason to use this is because you need to access the + * device list in interrupt context. Otherwise you really want to use + * shost_for_each_device instead. + */ +#define __shost_for_each_device(sdev, shost) \ + list_for_each_entry((sdev), &((shost)->__devices), siblings) + +extern void scsi_adjust_queue_depth(struct scsi_device *, int, int); +extern int scsi_track_queue_full(struct scsi_device *, int); + +extern int scsi_set_medium_removal(struct scsi_device *, char); + +extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, + unsigned char *buffer, int len, int timeout, + int retries, struct scsi_mode_data *data, + struct scsi_sense_hdr *); +extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, + int modepage, unsigned char *buffer, int len, + int timeout, int retries, + struct scsi_mode_data *data, + struct scsi_sense_hdr *); +extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, + int retries, struct scsi_sense_hdr *sshdr); +extern int scsi_device_set_state(struct scsi_device *sdev, + enum scsi_device_state state); +extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, + gfp_t gfpflags); +extern void sdev_evt_send(struct scsi_device *sdev, struct scsi_event *evt); +extern void sdev_evt_send_simple(struct scsi_device *sdev, + enum scsi_device_event evt_type, gfp_t gfpflags); +extern int scsi_device_quiesce(struct scsi_device *sdev); +extern void scsi_device_resume(struct scsi_device *sdev); +extern void scsi_target_quiesce(struct scsi_target *); +extern void scsi_target_resume(struct scsi_target *); +extern void scsi_scan_target(struct device *parent, unsigned int channel, + unsigned int id, unsigned int lun, int rescan); +extern void scsi_target_reap(struct scsi_target *); +extern void scsi_target_block(struct device *); +extern void scsi_target_unblock(struct device *); +extern void scsi_remove_target(struct device *); +extern void int_to_scsilun(unsigned int, struct scsi_lun *); +extern int scsilun_to_int(struct scsi_lun *); +extern const char *scsi_device_state_name(enum scsi_device_state); +extern int scsi_is_sdev_device(const struct device *); +extern int scsi_is_target_device(const struct device *); +extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + unsigned char *sense, int timeout, int retries, + int flag, int *resid); +extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + struct scsi_sense_hdr *, int timeout, int retries, + int *resid); +extern int scsi_execute_async(struct scsi_device *sdev, + const unsigned char *cmd, int cmd_len, int data_direction, + void *buffer, unsigned bufflen, int use_sg, + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); + +static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) +{ + return device_reprobe(&sdev->sdev_gendev); +} + +static inline unsigned int sdev_channel(struct scsi_device *sdev) +{ + return sdev->channel; +} + +static inline unsigned int sdev_id(struct scsi_device *sdev) +{ + return sdev->id; +} + +#define scmd_id(scmd) sdev_id((scmd)->device) +#define scmd_channel(scmd) sdev_channel((scmd)->device) + +/* + * checks for positions of the SCSI state machine + */ +static inline int scsi_device_online(struct scsi_device *sdev) +{ + return sdev->sdev_state != SDEV_OFFLINE; +} +static inline int scsi_device_blocked(struct scsi_device *sdev) +{ + return sdev->sdev_state == SDEV_BLOCK || + sdev->sdev_state == SDEV_CREATED_BLOCK; +} +static inline int scsi_device_created(struct scsi_device *sdev) +{ + return sdev->sdev_state == SDEV_CREATED || + sdev->sdev_state == SDEV_CREATED_BLOCK; +} + +/* accessor functions for the SCSI parameters */ +static inline int scsi_device_sync(struct scsi_device *sdev) +{ + return sdev->sdtr; +} +static inline int scsi_device_wide(struct scsi_device *sdev) +{ + return sdev->wdtr; +} +static inline int scsi_device_dt(struct scsi_device *sdev) +{ + return sdev->ppr; +} +static inline int scsi_device_dt_only(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return (sdev->inquiry[56] & 0x0c) == 0x04; +} +static inline int scsi_device_ius(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return sdev->inquiry[56] & 0x01; +} +static inline int scsi_device_qas(struct scsi_device *sdev) +{ + if (sdev->inquiry_len < 57) + return 0; + return sdev->inquiry[56] & 0x02; +} +static inline int scsi_device_enclosure(struct scsi_device *sdev) +{ + return sdev->inquiry[6] & (1<<6); +} + +static inline int scsi_device_protection(struct scsi_device *sdev) +{ + return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0); +} + +#define MODULE_ALIAS_SCSI_DEVICE(type) \ + MODULE_ALIAS("scsi:t-" __stringify(type) "*") +#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" + +#endif /* _SCSI_SCSI_DEVICE_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_devinfo.h b/libdde_linux26/contrib/include/scsi/scsi_devinfo.h new file mode 100644 index 00000000..b4ddd3b1 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_devinfo.h @@ -0,0 +1,33 @@ +#ifndef _SCSI_SCSI_DEVINFO_H +#define _SCSI_SCSI_DEVINFO_H +/* + * Flags for SCSI devices that need special treatment + */ +#define BLIST_NOLUN 0x001 /* Only scan LUN 0 */ +#define BLIST_FORCELUN 0x002 /* Known to have LUNs, force scanning, + deprecated: Use max_luns=N */ +#define BLIST_BORKEN 0x004 /* Flag for broken handshaking */ +#define BLIST_KEY 0x008 /* unlock by special command */ +#define BLIST_SINGLELUN 0x010 /* Do not use LUNs in parallel */ +#define BLIST_NOTQ 0x020 /* Buggy Tagged Command Queuing */ +#define BLIST_SPARSELUN 0x040 /* Non consecutive LUN numbering */ +#define BLIST_MAX5LUN 0x080 /* Avoid LUNS >= 5 */ +#define BLIST_ISROM 0x100 /* Treat as (removable) CD-ROM */ +#define BLIST_LARGELUN 0x200 /* LUNs past 7 on a SCSI-2 device */ +#define BLIST_INQUIRY_36 0x400 /* override additional length field */ +#define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */ +#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */ +#define BLIST_MS_SKIP_PAGE_08 0x2000 /* do not send ms page 0x08 */ +#define BLIST_MS_SKIP_PAGE_3F 0x4000 /* do not send ms page 0x3f */ +#define BLIST_USE_10_BYTE_MS 0x8000 /* use 10 byte ms before 6 byte ms */ +#define BLIST_MS_192_BYTES_FOR_3F 0x10000 /* 192 byte ms page 0x3f request */ +#define BLIST_REPORTLUN2 0x20000 /* try REPORT_LUNS even for SCSI-2 devs + (if HBA supports more than 8 LUNs) */ +#define BLIST_NOREPORTLUN 0x40000 /* don't try REPORT_LUNS scan (SCSI-3 devs) */ +#define BLIST_NOT_LOCKABLE 0x80000 /* don't use PREVENT-ALLOW commands */ +#define BLIST_NO_ULD_ATTACH 0x100000 /* device is actually for RAID config */ +#define BLIST_SELECT_NO_ATN 0x200000 /* select without ATN */ +#define BLIST_RETRY_HWERROR 0x400000 /* retry HARDWARE_ERROR */ +#define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */ +#define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ +#endif diff --git a/libdde_linux26/contrib/include/scsi/scsi_dh.h b/libdde_linux26/contrib/include/scsi/scsi_dh.h new file mode 100644 index 00000000..33efce20 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_dh.h @@ -0,0 +1,80 @@ +/* + * Header file for SCSI device handler infrastruture. + * + * Modified version of patches posted by Mike Christie <michaelc@cs.wisc.edu> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright IBM Corporation, 2007 + * Authors: + * Chandra Seetharaman <sekharan@us.ibm.com> + * Mike Anderson <andmike@linux.vnet.ibm.com> + */ + +#include <scsi/scsi_device.h> + +enum { + SCSI_DH_OK = 0, + /* + * device errors + */ + SCSI_DH_DEV_FAILED, /* generic device error */ + SCSI_DH_DEV_TEMP_BUSY, + SCSI_DH_DEV_UNSUPP, /* device handler not supported */ + SCSI_DH_DEVICE_MAX, /* max device blkerr definition */ + + /* + * transport errors + */ + SCSI_DH_NOTCONN = SCSI_DH_DEVICE_MAX + 1, + SCSI_DH_CONN_FAILURE, + SCSI_DH_TRANSPORT_MAX, /* max transport blkerr definition */ + + /* + * driver and generic errors + */ + SCSI_DH_IO = SCSI_DH_TRANSPORT_MAX + 1, /* generic error */ + SCSI_DH_INVALID_IO, + SCSI_DH_RETRY, /* retry the req, but not immediately */ + SCSI_DH_IMM_RETRY, /* immediately retry the req */ + SCSI_DH_TIMED_OUT, + SCSI_DH_RES_TEMP_UNAVAIL, + SCSI_DH_DEV_OFFLINED, + SCSI_DH_NOSYS, + SCSI_DH_DRIVER_MAX, +}; +#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) +extern int scsi_dh_activate(struct request_queue *); +extern int scsi_dh_handler_exist(const char *); +extern int scsi_dh_attach(struct request_queue *, const char *); +extern void scsi_dh_detach(struct request_queue *); +#else +static inline int scsi_dh_activate(struct request_queue *req) +{ + return 0; +} +static inline int scsi_dh_handler_exist(const char *name) +{ + return 0; +} +static inline int scsi_dh_attach(struct request_queue *req, const char *name) +{ + return SCSI_DH_NOSYS; +} +static inline void scsi_dh_detach(struct request_queue *q) +{ + return; +} +#endif diff --git a/libdde_linux26/contrib/include/scsi/scsi_driver.h b/libdde_linux26/contrib/include/scsi/scsi_driver.h new file mode 100644 index 00000000..1f5ca7f6 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_driver.h @@ -0,0 +1,36 @@ +#ifndef _SCSI_SCSI_DRIVER_H +#define _SCSI_SCSI_DRIVER_H + +#include <linux/device.h> + +struct module; +struct scsi_cmnd; +struct scsi_device; +struct request; +struct request_queue; + + +struct scsi_driver { + struct module *owner; + struct device_driver gendrv; + + void (*rescan)(struct device *); + int (*done)(struct scsi_cmnd *); +}; +#define to_scsi_driver(drv) \ + container_of((drv), struct scsi_driver, gendrv) + +extern int scsi_register_driver(struct device_driver *); +#define scsi_unregister_driver(drv) \ + driver_unregister(drv); + +extern int scsi_register_interface(struct class_interface *); +#define scsi_unregister_interface(intf) \ + class_interface_unregister(intf) + +int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); +int scsi_prep_return(struct request_queue *q, struct request *req, int ret); + +#endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_eh.h b/libdde_linux26/contrib/include/scsi/scsi_eh.h new file mode 100644 index 00000000..06a87908 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_eh.h @@ -0,0 +1,95 @@ +#ifndef _SCSI_SCSI_EH_H +#define _SCSI_SCSI_EH_H + +#include <linux/scatterlist.h> + +#include <scsi/scsi_cmnd.h> +struct scsi_device; +struct Scsi_Host; + +/* + * This is a slightly modified SCSI sense "descriptor" format header. + * The addition is to allow the 0x70 and 0x71 response codes. The idea + * is to place the salient data from either "fixed" or "descriptor" sense + * format into one structure to ease application processing. + * + * The original sense buffer should be kept around for those cases + * in which more information is required (e.g. the LBA of a MEDIUM ERROR). + */ +struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ + u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ + u8 sense_key; + u8 asc; + u8 ascq; + u8 byte4; + u8 byte5; + u8 byte6; + u8 additional_length; /* always 0 for fixed sense format */ +}; + +static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) +{ + if (!sshdr) + return 0; + + return (sshdr->response_code & 0x70) == 0x70; +} + + +extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, + struct list_head *done_q); +extern void scsi_eh_flush_done_q(struct list_head *done_q); +extern void scsi_report_bus_reset(struct Scsi_Host *, int); +extern void scsi_report_device_reset(struct Scsi_Host *, int, int); +extern int scsi_block_when_processing_errors(struct scsi_device *); +extern int scsi_normalize_sense(const u8 *sense_buffer, int sb_len, + struct scsi_sense_hdr *sshdr); +extern int scsi_command_normalize_sense(struct scsi_cmnd *cmd, + struct scsi_sense_hdr *sshdr); + +static inline int scsi_sense_is_deferred(struct scsi_sense_hdr *sshdr) +{ + return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); +} + +extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, + int desc_type); + +extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, + u64 * info_out); + +extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); + +/* + * Reset request from external source + */ +#define SCSI_TRY_RESET_DEVICE 1 +#define SCSI_TRY_RESET_BUS 2 +#define SCSI_TRY_RESET_HOST 3 +#define SCSI_TRY_RESET_TARGET 4 + +extern int scsi_reset_provider(struct scsi_device *, int); + +struct scsi_eh_save { + /* saved state */ + int result; + enum dma_data_direction data_direction; + unsigned underflow; + unsigned char cmd_len; + unsigned char prot_op; + unsigned char *cmnd; + struct scsi_data_buffer sdb; + struct request *next_rq; + /* new command support */ + unsigned char eh_cmnd[BLK_MAX_CDB]; + struct scatterlist sense_sgl; +}; + +extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, + struct scsi_eh_save *ses, unsigned char *cmnd, + int cmnd_size, unsigned sense_bytes); + +extern void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, + struct scsi_eh_save *ses); + +#endif /* _SCSI_SCSI_EH_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_host.h b/libdde_linux26/contrib/include/scsi/scsi_host.h new file mode 100644 index 00000000..d123ca84 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_host.h @@ -0,0 +1,841 @@ +#ifndef _SCSI_SCSI_HOST_H +#define _SCSI_SCSI_HOST_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/types.h> +#include <linux/workqueue.h> +#include <linux/mutex.h> +#include <scsi/scsi.h> + +struct request_queue; +struct block_device; +struct completion; +struct module; +struct scsi_cmnd; +struct scsi_device; +struct scsi_target; +struct Scsi_Host; +struct scsi_host_cmd_pool; +struct scsi_transport_template; +struct blk_queue_tags; + + +/* + * The various choices mean: + * NONE: Self evident. Host adapter is not capable of scatter-gather. + * ALL: Means that the host adapter module can do scatter-gather, + * and that there is no limit to the size of the table to which + * we scatter/gather data. The value we set here is the maximum + * single element sglist. To use chained sglists, the adapter + * has to set a value beyond ALL (and correctly use the chain + * handling API. + * Anything else: Indicates the maximum number of chains that can be + * used in one scatter-gather request. + */ +#define SG_NONE 0 +#define SG_ALL SCSI_MAX_SG_SEGMENTS + +#define MODE_UNKNOWN 0x00 +#define MODE_INITIATOR 0x01 +#define MODE_TARGET 0x02 + +#define DISABLE_CLUSTERING 0 +#define ENABLE_CLUSTERING 1 + +struct scsi_host_template { + struct module *module; + const char *name; + + /* + * Used to initialize old-style drivers. For new-style drivers + * just perform all work in your module initialization function. + * + * Status: OBSOLETE + */ + int (* detect)(struct scsi_host_template *); + + /* + * Used as unload callback for hosts with old-style drivers. + * + * Status: OBSOLETE + */ + int (* release)(struct Scsi_Host *); + + /* + * The info function will return whatever useful information the + * developer sees fit. If not provided, then the name field will + * be used instead. + * + * Status: OPTIONAL + */ + const char *(* info)(struct Scsi_Host *); + + /* + * Ioctl interface + * + * Status: OPTIONAL + */ + int (* ioctl)(struct scsi_device *dev, int cmd, void __user *arg); + + +#ifdef CONFIG_COMPAT + /* + * Compat handler. Handle 32bit ABI. + * When unknown ioctl is passed return -ENOIOCTLCMD. + * + * Status: OPTIONAL + */ + int (* compat_ioctl)(struct scsi_device *dev, int cmd, void __user *arg); +#endif + + /* + * The queuecommand function is used to queue up a scsi + * command block to the LLDD. When the driver finished + * processing the command the done callback is invoked. + * + * If queuecommand returns 0, then the HBA has accepted the + * command. The done() function must be called on the command + * when the driver has finished with it. (you may call done on the + * command before queuecommand returns, but in this case you + * *must* return 0 from queuecommand). + * + * Queuecommand may also reject the command, in which case it may + * not touch the command and must not call done() for it. + * + * There are two possible rejection returns: + * + * SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but + * allow commands to other devices serviced by this host. + * + * SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this + * host temporarily. + * + * For compatibility, any other non-zero return is treated the + * same as SCSI_MLQUEUE_HOST_BUSY. + * + * NOTE: "temporarily" means either until the next command for# + * this device/host completes, or a period of time determined by + * I/O pressure in the system if there are no other outstanding + * commands. + * + * STATUS: REQUIRED + */ + int (* queuecommand)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + + /* + * The transfer functions are used to queue a scsi command to + * the LLD. When the driver is finished processing the command + * the done callback is invoked. + * + * This is called to inform the LLD to transfer + * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the + * number of scatterlist entried in the command and + * scsi_sglist(cmd) returns the scatterlist. + * + * return values: see queuecommand + * + * If the LLD accepts the cmd, it should set the result to an + * appropriate value when completed before calling the done function. + * + * STATUS: REQUIRED FOR TARGET DRIVERS + */ + /* TODO: rename */ + int (* transfer_response)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); + + /* + * This is an error handling strategy routine. You don't need to + * define one of these if you don't want to - there is a default + * routine that is present that should work in most cases. For those + * driver authors that have the inclination and ability to write their + * own strategy routine, this is where it is specified. Note - the + * strategy routine is *ALWAYS* run in the context of the kernel eh + * thread. Thus you are guaranteed to *NOT* be in an interrupt + * handler when you execute this, and you are also guaranteed to + * *NOT* have any other commands being queued while you are in the + * strategy routine. When you return from this function, operations + * return to normal. + * + * See scsi_error.c scsi_unjam_host for additional comments about + * what this function should and should not be attempting to do. + * + * Status: REQUIRED (at least one of them) + */ + int (* eh_abort_handler)(struct scsi_cmnd *); + int (* eh_device_reset_handler)(struct scsi_cmnd *); + int (* eh_target_reset_handler)(struct scsi_cmnd *); + int (* eh_bus_reset_handler)(struct scsi_cmnd *); + int (* eh_host_reset_handler)(struct scsi_cmnd *); + + /* + * Before the mid layer attempts to scan for a new device where none + * currently exists, it will call this entry in your driver. Should + * your driver need to allocate any structs or perform any other init + * items in order to send commands to a currently unused target/lun + * combo, then this is where you can perform those allocations. This + * is specifically so that drivers won't have to perform any kind of + * "is this a new device" checks in their queuecommand routine, + * thereby making the hot path a bit quicker. + * + * Return values: 0 on success, non-0 on failure + * + * Deallocation: If we didn't find any devices at this ID, you will + * get an immediate call to slave_destroy(). If we find something + * here then you will get a call to slave_configure(), then the + * device will be used for however long it is kept around, then when + * the device is removed from the system (or * possibly at reboot + * time), you will then get a call to slave_destroy(). This is + * assuming you implement slave_configure and slave_destroy. + * However, if you allocate memory and hang it off the device struct, + * then you must implement the slave_destroy() routine at a minimum + * in order to avoid leaking memory + * each time a device is tore down. + * + * Status: OPTIONAL + */ + int (* slave_alloc)(struct scsi_device *); + + /* + * Once the device has responded to an INQUIRY and we know the + * device is online, we call into the low level driver with the + * struct scsi_device *. If the low level device driver implements + * this function, it *must* perform the task of setting the queue + * depth on the device. All other tasks are optional and depend + * on what the driver supports and various implementation details. + * + * Things currently recommended to be handled at this time include: + * + * 1. Setting the device queue depth. Proper setting of this is + * described in the comments for scsi_adjust_queue_depth. + * 2. Determining if the device supports the various synchronous + * negotiation protocols. The device struct will already have + * responded to INQUIRY and the results of the standard items + * will have been shoved into the various device flag bits, eg. + * device->sdtr will be true if the device supports SDTR messages. + * 3. Allocating command structs that the device will need. + * 4. Setting the default timeout on this device (if needed). + * 5. Anything else the low level driver might want to do on a device + * specific setup basis... + * 6. Return 0 on success, non-0 on error. The device will be marked + * as offline on error so that no access will occur. If you return + * non-0, your slave_destroy routine will never get called for this + * device, so don't leave any loose memory hanging around, clean + * up after yourself before returning non-0 + * + * Status: OPTIONAL + */ + int (* slave_configure)(struct scsi_device *); + + /* + * Immediately prior to deallocating the device and after all activity + * has ceased the mid layer calls this point so that the low level + * driver may completely detach itself from the scsi device and vice + * versa. The low level driver is responsible for freeing any memory + * it allocated in the slave_alloc or slave_configure calls. + * + * Status: OPTIONAL + */ + void (* slave_destroy)(struct scsi_device *); + + /* + * Before the mid layer attempts to scan for a new device attached + * to a target where no target currently exists, it will call this + * entry in your driver. Should your driver need to allocate any + * structs or perform any other init items in order to send commands + * to a currently unused target, then this is where you can perform + * those allocations. + * + * Return values: 0 on success, non-0 on failure + * + * Status: OPTIONAL + */ + int (* target_alloc)(struct scsi_target *); + + /* + * Immediately prior to deallocating the target structure, and + * after all activity to attached scsi devices has ceased, the + * midlayer calls this point so that the driver may deallocate + * and terminate any references to the target. + * + * Status: OPTIONAL + */ + void (* target_destroy)(struct scsi_target *); + + /* + * If a host has the ability to discover targets on its own instead + * of scanning the entire bus, it can fill in this function and + * call scsi_scan_host(). This function will be called periodically + * until it returns 1 with the scsi_host and the elapsed time of + * the scan in jiffies. + * + * Status: OPTIONAL + */ + int (* scan_finished)(struct Scsi_Host *, unsigned long); + + /* + * If the host wants to be called before the scan starts, but + * after the midlayer has set up ready for the scan, it can fill + * in this function. + * + * Status: OPTIONAL + */ + void (* scan_start)(struct Scsi_Host *); + + /* + * Fill in this function to allow the queue depth of this host + * to be changeable (on a per device basis). Returns either + * the current queue depth setting (may be different from what + * was passed in) or an error. An error should only be + * returned if the requested depth is legal but the driver was + * unable to set it. If the requested depth is illegal, the + * driver should set and return the closest legal queue depth. + * + * Status: OPTIONAL + */ + int (* change_queue_depth)(struct scsi_device *, int); + + /* + * Fill in this function to allow the changing of tag types + * (this also allows the enabling/disabling of tag command + * queueing). An error should only be returned if something + * went wrong in the driver while trying to set the tag type. + * If the driver doesn't support the requested tag type, then + * it should set the closest type it does support without + * returning an error. Returns the actual tag type set. + * + * Status: OPTIONAL + */ + int (* change_queue_type)(struct scsi_device *, int); + + /* + * This function determines the BIOS parameters for a given + * harddisk. These tend to be numbers that are made up by + * the host adapter. Parameters: + * size, device, list (heads, sectors, cylinders) + * + * Status: OPTIONAL + */ + int (* bios_param)(struct scsi_device *, struct block_device *, + sector_t, int []); + + /* + * Can be used to export driver statistics and other infos to the + * world outside the kernel ie. userspace and it also provides an + * interface to feed the driver with information. + * + * Status: OBSOLETE + */ + int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int); + + /* + * This is an optional routine that allows the transport to become + * involved when a scsi io timer fires. The return value tells the + * timer routine how to finish the io timeout handling: + * EH_HANDLED: I fixed the error, please complete the command + * EH_RESET_TIMER: I need more time, reset the timer and + * begin counting again + * EH_NOT_HANDLED Begin normal error recovery + * + * Status: OPTIONAL + */ + enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); + + /* + * Name of proc directory + */ + const char *proc_name; + + /* + * Used to store the procfs directory if a driver implements the + * proc_info method. + */ + struct proc_dir_entry *proc_dir; + + /* + * This determines if we will use a non-interrupt driven + * or an interrupt driven scheme. It is set to the maximum number + * of simultaneous commands a given host adapter will accept. + */ + int can_queue; + + /* + * In many instances, especially where disconnect / reconnect are + * supported, our host also has an ID on the SCSI bus. If this is + * the case, then it must be reserved. Please set this_id to -1 if + * your setup is in single initiator mode, and the host lacks an + * ID. + */ + int this_id; + + /* + * This determines the degree to which the host adapter is capable + * of scatter-gather. + */ + unsigned short sg_tablesize; + + /* + * Set this if the host adapter has limitations beside segment count. + */ + unsigned short max_sectors; + + /* + * DMA scatter gather segment boundary limit. A segment crossing this + * boundary will be split in two. + */ + unsigned long dma_boundary; + + /* + * This specifies "machine infinity" for host templates which don't + * limit the transfer size. Note this limit represents an absolute + * maximum, and may be over the transfer limits allowed for + * individual devices (e.g. 256 for SCSI-1). + */ +#define SCSI_DEFAULT_MAX_SECTORS 1024 + + /* + * True if this host adapter can make good use of linked commands. + * This will allow more than one command to be queued to a given + * unit on a given host. Set this to the maximum number of command + * blocks to be provided for each device. Set this to 1 for one + * command block per lun, 2 for two, etc. Do not set this to 0. + * You should make sure that the host adapter will do the right thing + * before you try setting this above 1. + */ + short cmd_per_lun; + + /* + * present contains counter indicating how many boards of this + * type were found when we did the scan. + */ + unsigned char present; + + /* + * This specifies the mode that a LLD supports. + */ + unsigned supported_mode:2; + + /* + * True if this host adapter uses unchecked DMA onto an ISA bus. + */ + unsigned unchecked_isa_dma:1; + + /* + * True if this host adapter can make good use of clustering. + * I originally thought that if the tablesize was large that it + * was a waste of CPU cycles to prepare a cluster list, but + * it works out that the Buslogic is faster if you use a smaller + * number of segments (i.e. use clustering). I guess it is + * inefficient. + */ + unsigned use_clustering:1; + + /* + * True for emulated SCSI host adapters (e.g. ATAPI). + */ + unsigned emulated:1; + + /* + * True if the low-level driver performs its own reset-settle delays. + */ + unsigned skip_settle_delay:1; + + /* + * True if we are using ordered write support. + */ + unsigned ordered_tag:1; + + /* + * Countdown for host blocking with no commands outstanding. + */ + unsigned int max_host_blocked; + + /* + * Default value for the blocking. If the queue is empty, + * host_blocked counts down in the request_fn until it restarts + * host operations as zero is reached. + * + * FIXME: This should probably be a value in the template + */ +#define SCSI_DEFAULT_HOST_BLOCKED 7 + + /* + * Pointer to the sysfs class properties for this host, NULL terminated. + */ + struct device_attribute **shost_attrs; + + /* + * Pointer to the SCSI device properties for this host, NULL terminated. + */ + struct device_attribute **sdev_attrs; + + /* + * List of hosts per template. + * + * This is only for use by scsi_module.c for legacy templates. + * For these access to it is synchronized implicitly by + * module_init/module_exit. + */ + struct list_head legacy_hosts; +}; + +/* + * shost state: If you alter this, you also need to alter scsi_sysfs.c + * (for the ascii descriptions) and the state model enforcer: + * scsi_host_set_state() + */ +enum scsi_host_state { + SHOST_CREATED = 1, + SHOST_RUNNING, + SHOST_CANCEL, + SHOST_DEL, + SHOST_RECOVERY, + SHOST_CANCEL_RECOVERY, + SHOST_DEL_RECOVERY, +}; + +struct Scsi_Host { + /* + * __devices is protected by the host_lock, but you should + * usually use scsi_device_lookup / shost_for_each_device + * to access it and don't care about locking yourself. + * In the rare case of beeing in irq context you can use + * their __ prefixed variants with the lock held. NEVER + * access this list directly from a driver. + */ + struct list_head __devices; + struct list_head __targets; + + struct scsi_host_cmd_pool *cmd_pool; + spinlock_t free_list_lock; + struct list_head free_list; /* backup store of cmd structs */ + struct list_head starved_list; + + spinlock_t default_lock; + spinlock_t *host_lock; + + struct mutex scan_mutex;/* serialize scanning activity */ + + struct list_head eh_cmd_q; + struct task_struct * ehandler; /* Error recovery thread. */ + struct completion * eh_action; /* Wait for specific actions on the + host. */ + wait_queue_head_t host_wait; + struct scsi_host_template *hostt; + struct scsi_transport_template *transportt; + + /* + * Area to keep a shared tag map (if needed, will be + * NULL if not). + */ + struct blk_queue_tag *bqt; + + /* + * The following two fields are protected with host_lock; + * however, eh routines can safely access during eh processing + * without acquiring the lock. + */ + unsigned int host_busy; /* commands actually active on low-level */ + unsigned int host_failed; /* commands that failed. */ + unsigned int host_eh_scheduled; /* EH scheduled without command */ + + unsigned int host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ + int resetting; /* if set, it means that last_reset is a valid value */ + unsigned long last_reset; + + /* + * These three parameters can be used to allow for wide scsi, + * and for host adapters that support multiple busses + * The first two should be set to 1 more than the actual max id + * or lun (i.e. 8 for normal systems). + */ + unsigned int max_id; + unsigned int max_lun; + unsigned int max_channel; + + /* + * This is a unique identifier that must be assigned so that we + * have some way of identifying each detected host adapter properly + * and uniquely. For hosts that do not support more than one card + * in the system at one time, this does not need to be set. It is + * initialized to 0 in scsi_register. + */ + unsigned int unique_id; + + /* + * The maximum length of SCSI commands that this host can accept. + * Probably 12 for most host adapters, but could be 16 for others. + * or 260 if the driver supports variable length cdbs. + * For drivers that don't set this field, a value of 12 is + * assumed. + */ + unsigned short max_cmd_len; + + int this_id; + int can_queue; + short cmd_per_lun; + short unsigned int sg_tablesize; + short unsigned int max_sectors; + unsigned long dma_boundary; + /* + * Used to assign serial numbers to the cmds. + * Protected by the host lock. + */ + unsigned long cmd_serial_number; + + unsigned active_mode:2; + unsigned unchecked_isa_dma:1; + unsigned use_clustering:1; + unsigned use_blk_tcq:1; + + /* + * Host has requested that no further requests come through for the + * time being. + */ + unsigned host_self_blocked:1; + + /* + * Host uses correct SCSI ordering not PC ordering. The bit is + * set for the minority of drivers whose authors actually read + * the spec ;). + */ + unsigned reverse_ordering:1; + + /* + * Ordered write support + */ + unsigned ordered_tag:1; + + /* Task mgmt function in progress */ + unsigned tmf_in_progress:1; + + /* Asynchronous scan in progress */ + unsigned async_scan:1; + + /* + * Optional work queue to be utilized by the transport + */ + char work_q_name[20]; + struct workqueue_struct *work_q; + + /* + * Host has rejected a command because it was busy. + */ + unsigned int host_blocked; + + /* + * Value host_blocked counts down from + */ + unsigned int max_host_blocked; + + /* Protection Information */ + unsigned int prot_capabilities; + unsigned char prot_guard_type; + + /* + * q used for scsi_tgt msgs, async events or any other requests that + * need to be processed in userspace + */ + struct request_queue *uspace_req_q; + + /* legacy crap */ + unsigned long base; + unsigned long io_port; + unsigned char n_io_port; + unsigned char dma_channel; + unsigned int irq; + + + enum scsi_host_state shost_state; + + /* ldm bits */ + struct device shost_gendev, shost_dev; + + /* + * List of hosts per template. + * + * This is only for use by scsi_module.c for legacy templates. + * For these access to it is synchronized implicitly by + * module_init/module_exit. + */ + struct list_head sht_legacy_list; + + /* + * Points to the transport data (if any) which is allocated + * separately + */ + void *shost_data; + + /* + * We should ensure that this is aligned, both for better performance + * and also because some compilers (m68k) don't automatically force + * alignment to a long boundary. + */ + unsigned long hostdata[0] /* Used for storage of host specific stuff */ + __attribute__ ((aligned (sizeof(unsigned long)))); +}; + +#define class_to_shost(d) \ + container_of(d, struct Scsi_Host, shost_dev) + +#define shost_printk(prefix, shost, fmt, a...) \ + dev_printk(prefix, &(shost)->shost_gendev, fmt, ##a) + +static inline void *shost_priv(struct Scsi_Host *shost) +{ + return (void *)shost->hostdata; +} + +int scsi_is_host_device(const struct device *); + +static inline struct Scsi_Host *dev_to_shost(struct device *dev) +{ + while (!scsi_is_host_device(dev)) { + if (!dev->parent) + return NULL; + dev = dev->parent; + } + return container_of(dev, struct Scsi_Host, shost_gendev); +} + +static inline int scsi_host_in_recovery(struct Scsi_Host *shost) +{ + return shost->shost_state == SHOST_RECOVERY || + shost->shost_state == SHOST_CANCEL_RECOVERY || + shost->shost_state == SHOST_DEL_RECOVERY || + shost->tmf_in_progress; +} + +extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); +extern void scsi_flush_work(struct Scsi_Host *); + +extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); +extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *); +extern void scsi_scan_host(struct Scsi_Host *); +extern void scsi_rescan_device(struct device *); +extern void scsi_remove_host(struct Scsi_Host *); +extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); +extern void scsi_host_put(struct Scsi_Host *t); +extern struct Scsi_Host *scsi_host_lookup(unsigned short); +extern const char *scsi_host_state_name(enum scsi_host_state); + +extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); + +static inline struct device *scsi_get_device(struct Scsi_Host *shost) +{ + return shost->shost_gendev.parent; +} + +/** + * scsi_host_scan_allowed - Is scanning of this host allowed + * @shost: Pointer to Scsi_Host. + **/ +static inline int scsi_host_scan_allowed(struct Scsi_Host *shost) +{ + return shost->shost_state == SHOST_RUNNING; +} + +extern void scsi_unblock_requests(struct Scsi_Host *); +extern void scsi_block_requests(struct Scsi_Host *); + +struct class_container; + +extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, + void (*) (struct request_queue *)); +/* + * These two functions are used to allocate and free a pseudo device + * which will connect to the host adapter itself rather than any + * physical device. You must deallocate when you are done with the + * thing. This physical pseudo-device isn't real and won't be available + * from any high-level drivers. + */ +extern void scsi_free_host_dev(struct scsi_device *); +extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); + +/* + * DIF defines the exchange of protection information between + * initiator and SBC block device. + * + * DIX defines the exchange of protection information between OS and + * initiator. + */ +enum scsi_host_prot_capabilities { + SHOST_DIF_TYPE1_PROTECTION = 1 << 0, /* T10 DIF Type 1 */ + SHOST_DIF_TYPE2_PROTECTION = 1 << 1, /* T10 DIF Type 2 */ + SHOST_DIF_TYPE3_PROTECTION = 1 << 2, /* T10 DIF Type 3 */ + + SHOST_DIX_TYPE0_PROTECTION = 1 << 3, /* DIX between OS and HBA only */ + SHOST_DIX_TYPE1_PROTECTION = 1 << 4, /* DIX with DIF Type 1 */ + SHOST_DIX_TYPE2_PROTECTION = 1 << 5, /* DIX with DIF Type 2 */ + SHOST_DIX_TYPE3_PROTECTION = 1 << 6, /* DIX with DIF Type 3 */ +}; + +/* + * SCSI hosts which support the Data Integrity Extensions must + * indicate their capabilities by setting the prot_capabilities using + * this call. + */ +static inline void scsi_host_set_prot(struct Scsi_Host *shost, unsigned int mask) +{ + shost->prot_capabilities = mask; +} + +static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) +{ + return shost->prot_capabilities; +} + +static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) +{ + switch (target_type) { + case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; + case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; + case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; + } + + return 0; +} + +static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) +{ + switch (target_type) { + case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; + case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; + case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; + case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; + } + + return 0; +} + +/* + * All DIX-capable initiators must support the T10-mandated CRC + * checksum. Controllers can optionally implement the IP checksum + * scheme which has much lower impact on system performance. Note + * that the main rationale for the checksum is to match integrity + * metadata with data. Detecting bit errors are a job for ECC memory + * and buses. + */ + +enum scsi_host_guard_type { + SHOST_DIX_GUARD_CRC = 1 << 0, + SHOST_DIX_GUARD_IP = 1 << 1, +}; + +static inline void scsi_host_set_guard(struct Scsi_Host *shost, unsigned char type) +{ + shost->prot_guard_type = type; +} + +static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) +{ + return shost->prot_guard_type; +} + +/* legacy interfaces */ +extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); +extern void scsi_unregister(struct Scsi_Host *); +extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state); + +#endif /* _SCSI_SCSI_HOST_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_ioctl.h b/libdde_linux26/contrib/include/scsi/scsi_ioctl.h new file mode 100644 index 00000000..b9006848 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_ioctl.h @@ -0,0 +1,48 @@ +#ifndef _SCSI_IOCTL_H +#define _SCSI_IOCTL_H + +#define SCSI_IOCTL_SEND_COMMAND 1 +#define SCSI_IOCTL_TEST_UNIT_READY 2 +#define SCSI_IOCTL_BENCHMARK_COMMAND 3 +#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */ +#define SCSI_IOCTL_START_UNIT 5 +#define SCSI_IOCTL_STOP_UNIT 6 +/* The door lock/unlock constants are compatible with Sun constants for + the cdrom */ +#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */ +#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */ + +#define SCSI_REMOVAL_PREVENT 1 +#define SCSI_REMOVAL_ALLOW 0 + +#ifdef __KERNEL__ + +struct scsi_device; + +/* + * Structures used for scsi_ioctl et al. + */ + +typedef struct scsi_ioctl_command { + unsigned int inlen; + unsigned int outlen; + unsigned char data[0]; +} Scsi_Ioctl_Command; + +typedef struct scsi_idlun { + __u32 dev_id; + __u32 host_unique_id; +} Scsi_Idlun; + +/* Fibre Channel WWN, port_id struct */ +typedef struct scsi_fctargaddress { + __u32 host_port_id; + unsigned char host_wwn[8]; // include NULL term. +} Scsi_FCTargAddress; + +extern int scsi_ioctl(struct scsi_device *, int, void __user *); +extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, + void __user *arg, int ndelay); + +#endif /* __KERNEL__ */ +#endif /* _SCSI_IOCTL_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_netlink.h b/libdde_linux26/contrib/include/scsi/scsi_netlink.h new file mode 100644 index 00000000..536752c4 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_netlink.h @@ -0,0 +1,147 @@ +/* + * SCSI Transport Netlink Interface + * Used for the posting of outbound SCSI transport events + * + * Copyright (C) 2006 James Smart, Emulex Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef SCSI_NETLINK_H +#define SCSI_NETLINK_H + +#include <linux/netlink.h> + + +/* + * This file intended to be included by both kernel and user space + */ + +/* Single Netlink Message type to send all SCSI Transport messages */ +#define SCSI_TRANSPORT_MSG NLMSG_MIN_TYPE + 1 + +/* SCSI Transport Broadcast Groups */ + /* leaving groups 0 and 1 unassigned */ +#define SCSI_NL_GRP_FC_EVENTS (1<<2) /* Group 2 */ +#define SCSI_NL_GRP_CNT 3 + + +/* SCSI_TRANSPORT_MSG event message header */ +struct scsi_nl_hdr { + uint8_t version; + uint8_t transport; + uint16_t magic; + uint16_t msgtype; + uint16_t msglen; +} __attribute__((aligned(sizeof(uint64_t)))); + +/* scsi_nl_hdr->version value */ +#define SCSI_NL_VERSION 1 + +/* scsi_nl_hdr->magic value */ +#define SCSI_NL_MAGIC 0xA1B2 + +/* scsi_nl_hdr->transport value */ +#define SCSI_NL_TRANSPORT 0 +#define SCSI_NL_TRANSPORT_FC 1 +#define SCSI_NL_MAX_TRANSPORTS 2 + +/* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */ + +/* + * GENERIC SCSI scsi_nl_hdr->msgtype Values + */ + /* kernel -> user */ +#define SCSI_NL_SHOST_VENDOR 0x0001 + /* user -> kernel */ +/* SCSI_NL_SHOST_VENDOR msgtype is kernel->user and user->kernel */ + + +/* + * Message Structures : + */ + +/* macro to round up message lengths to 8byte boundary */ +#define SCSI_NL_MSGALIGN(len) (((len) + 7) & ~7) + + +/* + * SCSI HOST Vendor Unique messages : + * SCSI_NL_SHOST_VENDOR + * + * Note: The Vendor Unique message payload will begin directly after + * this structure, with the length of the payload per vmsg_datalen. + * + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID + * formatting requirements specified below + */ +struct scsi_nl_host_vendor_msg { + struct scsi_nl_hdr snlh; /* must be 1st element ! */ + uint64_t vendor_id; + uint16_t host_no; + uint16_t vmsg_datalen; +} __attribute__((aligned(sizeof(uint64_t)))); + + +/* + * Vendor ID: + * If transports post vendor-unique events, they must pass a well-known + * 32-bit vendor identifier. This identifier consists of 8 bits indicating + * the "type" of identifier contained, and 24 bits of id data. + * + * Identifiers for each type: + * PCI : ID data is the 16 bit PCI Registered Vendor ID + */ +#define SCSI_NL_VID_TYPE_SHIFT 56 +#define SCSI_NL_VID_TYPE_MASK ((u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_TYPE_PCI ((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_ID_MASK (~ SCSI_NL_VID_TYPE_MASK) + + +#define INIT_SCSI_NL_HDR(hdr, t, mtype, mlen) \ + { \ + (hdr)->version = SCSI_NL_VERSION; \ + (hdr)->transport = t; \ + (hdr)->magic = SCSI_NL_MAGIC; \ + (hdr)->msgtype = mtype; \ + (hdr)->msglen = mlen; \ + } + + +#ifdef __KERNEL__ + +#include <scsi/scsi_host.h> + +/* Exported Kernel Interfaces */ +int scsi_nl_add_transport(u8 tport, + int (*msg_handler)(struct sk_buff *), + void (*event_handler)(struct notifier_block *, unsigned long, void *)); +void scsi_nl_remove_transport(u8 tport); + +int scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt, + int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload, + u32 len, u32 pid), + void (*nlevt_handler)(struct notifier_block *nb, + unsigned long event, void *notify_ptr)); +void scsi_nl_remove_driver(u64 vendor_id); + +void scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr); +int scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id, + char *data_buf, u32 data_len); + +#endif /* __KERNEL__ */ + +#endif /* SCSI_NETLINK_H */ + diff --git a/libdde_linux26/contrib/include/scsi/scsi_netlink_fc.h b/libdde_linux26/contrib/include/scsi/scsi_netlink_fc.h new file mode 100644 index 00000000..cbf76e47 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_netlink_fc.h @@ -0,0 +1,71 @@ +/* + * FC Transport Netlink Interface + * + * Copyright (C) 2006 James Smart, Emulex Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef SCSI_NETLINK_FC_H +#define SCSI_NETLINK_FC_H + +#include <scsi/scsi_netlink.h> + +/* + * This file intended to be included by both kernel and user space + */ + +/* + * FC Transport Message Types + */ + /* kernel -> user */ +#define FC_NL_ASYNC_EVENT 0x0100 + /* user -> kernel */ +/* none */ + + +/* + * Message Structures : + */ + +/* macro to round up message lengths to 8byte boundary */ +#define FC_NL_MSGALIGN(len) (((len) + 7) & ~7) + + +/* + * FC Transport Broadcast Event Message : + * FC_NL_ASYNC_EVENT + * + * Note: if Vendor Unique message, &event_data will be start of + * vendor unique payload, and the length of the payload is + * per event_datalen + * + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID + * formatting requirements specified in scsi_netlink.h + */ +struct fc_nl_event { + struct scsi_nl_hdr snlh; /* must be 1st element ! */ + uint64_t seconds; + uint64_t vendor_id; + uint16_t host_no; + uint16_t event_datalen; + uint32_t event_num; + uint32_t event_code; + uint32_t event_data; +} __attribute__((aligned(sizeof(uint64_t)))); + + +#endif /* SCSI_NETLINK_FC_H */ + diff --git a/libdde_linux26/contrib/include/scsi/scsi_tcq.h b/libdde_linux26/contrib/include/scsi/scsi_tcq.h new file mode 100644 index 00000000..17231385 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_tcq.h @@ -0,0 +1,178 @@ +#ifndef _SCSI_SCSI_TCQ_H +#define _SCSI_SCSI_TCQ_H + +#include <linux/blkdev.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_host.h> + +#define MSG_SIMPLE_TAG 0x20 +#define MSG_HEAD_TAG 0x21 +#define MSG_ORDERED_TAG 0x22 + +#define SCSI_NO_TAG (-1) /* identify no tag in use */ + + +#ifdef CONFIG_BLOCK + +/** + * scsi_get_tag_type - get the type of tag the device supports + * @sdev: the scsi device + * + * Notes: + * If the drive only supports simple tags, returns MSG_SIMPLE_TAG + * if it supports all tag types, returns MSG_ORDERED_TAG. + */ +static inline int scsi_get_tag_type(struct scsi_device *sdev) +{ + if (!sdev->tagged_supported) + return 0; + if (sdev->ordered_tags) + return MSG_ORDERED_TAG; + if (sdev->simple_tags) + return MSG_SIMPLE_TAG; + return 0; +} + +static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) +{ + switch (tag) { + case MSG_ORDERED_TAG: + sdev->ordered_tags = 1; + /* fall through */ + case MSG_SIMPLE_TAG: + sdev->simple_tags = 1; + break; + case 0: + /* fall through */ + default: + sdev->ordered_tags = 0; + sdev->simple_tags = 0; + break; + } +} +/** + * scsi_activate_tcq - turn on tag command queueing + * @SDpnt: device to turn on TCQ for + * @depth: queue depth + * + * Notes: + * Eventually, I hope depth would be the maximum depth + * the device could cope with and the real queue depth + * would be adjustable from 0 to depth. + **/ +static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) +{ + if (!sdev->tagged_supported) + return; + + if (!blk_queue_tagged(sdev->request_queue)) + blk_queue_init_tags(sdev->request_queue, depth, + sdev->host->bqt); + + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); +} + +/** + * scsi_deactivate_tcq - turn off tag command queueing + * @SDpnt: device to turn off TCQ for + **/ +static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) +{ + if (blk_queue_tagged(sdev->request_queue)) + blk_queue_free_tags(sdev->request_queue); + scsi_adjust_queue_depth(sdev, 0, depth); +} + +/** + * scsi_populate_tag_msg - place a tag message in a buffer + * @SCpnt: pointer to the Scsi_Cmnd for the tag + * @msg: pointer to the area to place the tag + * + * Notes: + * designed to create the correct type of tag message for the + * particular request. Returns the size of the tag message. + * May return 0 if TCQ is disabled for this device. + **/ +static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) +{ + struct request *req = cmd->request; + struct scsi_device *sdev = cmd->device; + + if (blk_rq_tagged(req)) { + if (sdev->ordered_tags && req->cmd_flags & REQ_HARDBARRIER) + *msg++ = MSG_ORDERED_TAG; + else + *msg++ = MSG_SIMPLE_TAG; + *msg++ = req->tag; + return 2; + } + + return 0; +} + +/** + * scsi_find_tag - find a tagged command by device + * @SDpnt: pointer to the ScSI device + * @tag: the tag number + * + * Notes: + * Only works with tags allocated by the generic blk layer. + **/ +static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) +{ + + struct request *req; + + if (tag != SCSI_NO_TAG) { + req = blk_queue_find_tag(sdev->request_queue, tag); + return req ? (struct scsi_cmnd *)req->special : NULL; + } + + /* single command, look in space */ + return sdev->current_cmnd; +} + +/** + * scsi_init_shared_tag_map - create a shared tag map + * @shost: the host to share the tag map among all devices + * @depth: the total depth of the map + */ +static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) +{ + /* + * If the shared tag map isn't already initialized, do it now. + * This saves callers from having to check ->bqt when setting up + * devices on the shared host (for libata) + */ + if (!shost->bqt) { + shost->bqt = blk_init_tags(depth); + if (!shost->bqt) + return -ENOMEM; + } + + return 0; +} + +/** + * scsi_host_find_tag - find the tagged command by host + * @shost: pointer to scsi_host + * @tag: tag of the scsi_cmnd + * + * Notes: + * Only works with tags allocated by the generic blk layer. + **/ +static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, + int tag) +{ + struct request *req; + + if (tag != SCSI_NO_TAG) { + req = blk_map_queue_find_tag(shost->bqt, tag); + return req ? (struct scsi_cmnd *)req->special : NULL; + } + return NULL; +} + +#endif /* CONFIG_BLOCK */ +#endif /* _SCSI_SCSI_TCQ_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_tgt.h b/libdde_linux26/contrib/include/scsi/scsi_tgt.h new file mode 100644 index 00000000..d0fefb96 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_tgt.h @@ -0,0 +1,21 @@ +/* + * SCSI target definitions + */ + +#include <linux/dma-mapping.h> + +struct Scsi_Host; +struct scsi_cmnd; +struct scsi_lun; + +extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *); +extern int scsi_tgt_alloc_queue(struct Scsi_Host *); +extern void scsi_tgt_free_queue(struct Scsi_Host *); +extern int scsi_tgt_queue_command(struct scsi_cmnd *, u64, struct scsi_lun *, u64); +extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, u64, int, u64, + struct scsi_lun *, void *); +extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *, + enum dma_data_direction, gfp_t); +extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *); +extern int scsi_tgt_it_nexus_create(struct Scsi_Host *, u64, char *); +extern int scsi_tgt_it_nexus_destroy(struct Scsi_Host *, u64); diff --git a/libdde_linux26/contrib/include/scsi/scsi_tgt_if.h b/libdde_linux26/contrib/include/scsi/scsi_tgt_if.h new file mode 100644 index 00000000..f2ee7c23 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_tgt_if.h @@ -0,0 +1,108 @@ +/* + * SCSI target kernel/user interface + * + * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> + * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef __SCSI_TARGET_IF_H +#define __SCSI_TARGET_IF_H + +/* user -> kernel */ +#define TGT_UEVENT_CMD_RSP 0x0001 +#define TGT_UEVENT_IT_NEXUS_RSP 0x0002 +#define TGT_UEVENT_TSK_MGMT_RSP 0x0003 + +/* kernel -> user */ +#define TGT_KEVENT_CMD_REQ 0x1001 +#define TGT_KEVENT_CMD_DONE 0x1002 +#define TGT_KEVENT_IT_NEXUS_REQ 0x1003 +#define TGT_KEVENT_TSK_MGMT_REQ 0x1004 + +struct tgt_event_hdr { + uint16_t version; + uint16_t status; + uint16_t type; + uint16_t len; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +struct tgt_event { + struct tgt_event_hdr hdr; + + union { + /* user-> kernel */ + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 tag; + aligned_u64 uaddr; + aligned_u64 sense_uaddr; + uint32_t len; + uint32_t sense_len; + uint8_t rw; + } cmd_rsp; + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 mid; + } tsk_mgmt_rsp; + struct { + __s32 host_no; + __s32 result; + aligned_u64 itn_id; + __u32 function; + } it_nexus_rsp; + + /* kernel -> user */ + struct { + int host_no; + uint32_t data_len; + aligned_u64 itn_id; + uint8_t scb[16]; + uint8_t lun[8]; + int attribute; + aligned_u64 tag; + } cmd_req; + struct { + int host_no; + int result; + aligned_u64 itn_id; + aligned_u64 tag; + } cmd_done; + struct { + int host_no; + int function; + aligned_u64 itn_id; + aligned_u64 tag; + uint8_t lun[8]; + aligned_u64 mid; + } tsk_mgmt_req; + struct { + __s32 host_no; + __u32 function; + aligned_u64 itn_id; + __u32 max_cmds; + __u8 initiator_id[16]; + } it_nexus_req; + } p; +} __attribute__ ((aligned (sizeof(uint64_t)))); + +#define TGT_RING_SIZE (1UL << 16) + +#endif diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport.h b/libdde_linux26/contrib/include/scsi/scsi_transport.h new file mode 100644 index 00000000..0de32cd4 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport.h @@ -0,0 +1,121 @@ +/* + * Transport specific attributes. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef SCSI_TRANSPORT_H +#define SCSI_TRANSPORT_H + +#include <linux/transport_class.h> +#include <linux/blkdev.h> +#include <scsi/scsi_host.h> +#include <scsi/scsi_device.h> + +struct scsi_transport_template { + /* the attribute containers */ + struct transport_container host_attrs; + struct transport_container target_attrs; + struct transport_container device_attrs; + + /* + * If set, called from sysfs and legacy procfs rescanning code. + */ + int (*user_scan)(struct Scsi_Host *, uint, uint, uint); + + /* The size of the specific transport attribute structure (a + * space of this size will be left at the end of the + * scsi_* structure */ + int device_size; + int device_private_offset; + int target_size; + int target_private_offset; + int host_size; + /* no private offset for the host; there's an alternative mechanism */ + + /* + * True if the transport wants to use a host-based work-queue + */ + unsigned int create_work_queue : 1; + + /* + * Allows a transport to override the default error handler. + */ + void (* eh_strategy_handler)(struct Scsi_Host *); + + /* + * This is an optional routine that allows the transport to become + * involved when a scsi io timer fires. The return value tells the + * timer routine how to finish the io timeout handling: + * EH_HANDLED: I fixed the error, please complete the command + * EH_RESET_TIMER: I need more time, reset the timer and + * begin counting again + * EH_NOT_HANDLED Begin normal error recovery + */ + enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); + + /* + * Used as callback for the completion of i_t_nexus request + * for target drivers. + */ + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + + /* + * Used as callback for the completion of task management + * request for target drivers. + */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); +}; + +#define transport_class_to_shost(tc) \ + dev_to_shost((tc)->parent) + + +/* Private area maintenance. The driver requested allocations come + * directly after the transport class allocations (if any). The idea + * is that you *must* call these only once. The code assumes that the + * initial values are the ones the transport specific code requires */ +static inline void +scsi_transport_reserve_target(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->target_private_offset != 0); + t->target_private_offset = ALIGN(t->target_size, sizeof(void *)); + t->target_size = t->target_private_offset + space; +} +static inline void +scsi_transport_reserve_device(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->device_private_offset != 0); + t->device_private_offset = ALIGN(t->device_size, sizeof(void *)); + t->device_size = t->device_private_offset + space; +} +static inline void * +scsi_transport_target_data(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(&starget->dev); + return (u8 *)starget->starget_data + + shost->transportt->target_private_offset; + +} +static inline void * +scsi_transport_device_data(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + return (u8 *)sdev->sdev_data + + shost->transportt->device_private_offset; +} + +#endif /* SCSI_TRANSPORT_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport_fc.h b/libdde_linux26/contrib/include/scsi/scsi_transport_fc.h new file mode 100644 index 00000000..c9184f75 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport_fc.h @@ -0,0 +1,763 @@ +/* + * FiberChannel transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ======== + * + * Copyright (C) 2004-2007 James Smart, Emulex Corporation + * Rewrite for host, target, device, and remote port attributes, + * statistics, and service functions... + * + */ +#ifndef SCSI_TRANSPORT_FC_H +#define SCSI_TRANSPORT_FC_H + +#include <linux/sched.h> +#include <scsi/scsi.h> +#include <scsi/scsi_netlink.h> + +struct scsi_transport_template; + + +/* + * FC Port definitions - Following FC HBAAPI guidelines + * + * Note: Not all binary values for the different fields match HBAAPI. + * Instead, we use densely packed ordinal values or enums. + * We get away with this as we never present the actual binary values + * externally. For sysfs, we always present the string that describes + * the value. Thus, an admin doesn't need a magic HBAAPI decoder ring + * to understand the values. The HBAAPI user-space library is free to + * convert the strings into the HBAAPI-specified binary values. + * + * Note: Not all HBAAPI-defined values are contained in the definitions + * below. Those not appropriate to an fc_host (e.g. FCP initiator) have + * been removed. + */ + +/* + * fc_port_type: If you alter this, you also need to alter scsi_transport_fc.c + * (for the ascii descriptions). + */ +enum fc_port_type { + FC_PORTTYPE_UNKNOWN, + FC_PORTTYPE_OTHER, + FC_PORTTYPE_NOTPRESENT, + FC_PORTTYPE_NPORT, /* Attached to FPort */ + FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */ + FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */ + FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */ + FC_PORTTYPE_NPIV, /* VPORT based on NPIV */ +}; + + +/* + * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c + * (for the ascii descriptions). + */ +enum fc_port_state { + FC_PORTSTATE_UNKNOWN, + FC_PORTSTATE_NOTPRESENT, + FC_PORTSTATE_ONLINE, + FC_PORTSTATE_OFFLINE, /* User has taken Port Offline */ + FC_PORTSTATE_BLOCKED, + FC_PORTSTATE_BYPASSED, + FC_PORTSTATE_DIAGNOSTICS, + FC_PORTSTATE_LINKDOWN, + FC_PORTSTATE_ERROR, + FC_PORTSTATE_LOOPBACK, + FC_PORTSTATE_DELETED, +}; + + +/* + * fc_vport_state: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_vport_state { + FC_VPORT_UNKNOWN, + FC_VPORT_ACTIVE, + FC_VPORT_DISABLED, + FC_VPORT_LINKDOWN, + FC_VPORT_INITIALIZING, + FC_VPORT_NO_FABRIC_SUPP, + FC_VPORT_NO_FABRIC_RSCS, + FC_VPORT_FABRIC_LOGOUT, + FC_VPORT_FABRIC_REJ_WWN, + FC_VPORT_FAILED, +}; + + + +/* + * FC Classes of Service + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report supported_classes). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_COS_UNSPECIFIED 0 +#define FC_COS_CLASS1 2 +#define FC_COS_CLASS2 4 +#define FC_COS_CLASS3 8 +#define FC_COS_CLASS4 0x10 +#define FC_COS_CLASS6 0x40 + +/* + * FC Port Speeds + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report supported_speeds). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver + incapable of reporting */ +#define FC_PORTSPEED_1GBIT 1 +#define FC_PORTSPEED_2GBIT 2 +#define FC_PORTSPEED_4GBIT 4 +#define FC_PORTSPEED_10GBIT 8 +#define FC_PORTSPEED_8GBIT 0x10 +#define FC_PORTSPEED_16GBIT 0x20 +#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ + +/* + * fc_tgtid_binding_type: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_tgtid_binding_type { + FC_TGTID_BIND_NONE, + FC_TGTID_BIND_BY_WWPN, + FC_TGTID_BIND_BY_WWNN, + FC_TGTID_BIND_BY_ID, +}; + +/* + * FC Port Roles + * Note: values are not enumerated, as they can be "or'd" together + * for reporting (e.g. report roles). If you alter this list, + * you also need to alter scsi_transport_fc.c (for the ascii descriptions). + */ +#define FC_PORT_ROLE_UNKNOWN 0x00 +#define FC_PORT_ROLE_FCP_TARGET 0x01 +#define FC_PORT_ROLE_FCP_INITIATOR 0x02 +#define FC_PORT_ROLE_IP_PORT 0x04 + +/* The following are for compatibility */ +#define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN +#define FC_RPORT_ROLE_FCP_TARGET FC_PORT_ROLE_FCP_TARGET +#define FC_RPORT_ROLE_FCP_INITIATOR FC_PORT_ROLE_FCP_INITIATOR +#define FC_RPORT_ROLE_IP_PORT FC_PORT_ROLE_IP_PORT + + +/* Macro for use in defining Virtual Port attributes */ +#define FC_VPORT_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_vport_##_name = \ + __ATTR(_name,_mode,_show,_store) + +/* + * fc_vport_identifiers: This set of data contains all elements + * to uniquely identify and instantiate a FC virtual port. + * + * Notes: + * symbolic_name: The driver is to append the symbolic_name string data + * to the symbolic_node_name data that it generates by default. + * the resulting combination should then be registered with the switch. + * It is expected that things like Xen may stuff a VM title into + * this field. + */ +#define FC_VPORT_SYMBOLIC_NAMELEN 64 +struct fc_vport_identifiers { + u64 node_name; + u64 port_name; + u32 roles; + bool disable; + enum fc_port_type vport_type; /* only FC_PORTTYPE_NPIV allowed */ + char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; +}; + +/* + * FC Virtual Port Attributes + * + * This structure exists for each FC port is a virtual FC port. Virtual + * ports share the physical link with the Physical port. Each virtual + * ports has a unique presense on the SAN, and may be instantiated via + * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a + * unique presense, each vport has it's own view of the fabric, + * authentication privilege, and priorities. + * + * A virtual port may support 1 or more FC4 roles. Typically it is a + * FCP Initiator. It could be a FCP Target, or exist sole for an IP over FC + * roles. FC port attributes for the vport will be reported on any + * fc_host class object allocated for an FCP Initiator. + * + * -- + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after receiving the fc_vport structure + * via the vport_create() call from the transport. + * The transport fully manages all get functions w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +struct fc_vport { + /* Fixed Attributes */ + + /* Dynamic Attributes */ + + /* Private (Transport-managed) Attributes */ + enum fc_vport_state vport_state; + enum fc_vport_state vport_last_state; + u64 node_name; + u64 port_name; + u32 roles; + u32 vport_id; /* Admin Identifier for the vport */ + enum fc_port_type vport_type; + char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; + + /* exported data */ + void *dd_data; /* Used for driver-specific storage */ + + /* internal data */ + struct Scsi_Host *shost; /* Physical Port Parent */ + unsigned int channel; + u32 number; + u8 flags; + struct list_head peers; + struct device dev; + struct work_struct vport_delete_work; +} __attribute__((aligned(sizeof(unsigned long)))); + +/* bit field values for struct fc_vport "flags" field: */ +#define FC_VPORT_CREATING 0x01 +#define FC_VPORT_DELETING 0x02 +#define FC_VPORT_DELETED 0x04 +#define FC_VPORT_DEL 0x06 /* Any DELETE state */ + +#define dev_to_vport(d) \ + container_of(d, struct fc_vport, dev) +#define transport_class_to_vport(dev) \ + dev_to_vport(dev->parent) +#define vport_to_shost(v) \ + (v->shost) +#define vport_to_shost_channel(v) \ + (v->channel) +#define vport_to_parent(v) \ + (v->dev.parent) + + +/* Error return codes for vport_create() callback */ +#define VPCERR_UNSUPPORTED -ENOSYS /* no driver/adapter + support */ +#define VPCERR_BAD_WWN -ENOTUNIQ /* driver validation + of WWNs failed */ +#define VPCERR_NO_FABRIC_SUPP -EOPNOTSUPP /* Fabric connection + is loop or the + Fabric Port does + not support NPIV */ + +/* + * fc_rport_identifiers: This set of data contains all elements + * to uniquely identify a remote FC port. The driver uses this data + * to report the existence of a remote FC port in the topology. Internally, + * the transport uses this data for attributes and to manage consistent + * target id bindings. + */ +struct fc_rport_identifiers { + u64 node_name; + u64 port_name; + u32 port_id; + u32 roles; +}; + + +/* Macro for use in defining Remote Port attributes */ +#define FC_RPORT_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_rport_##_name = \ + __ATTR(_name,_mode,_show,_store) + + +/* + * FC Remote Port Attributes + * + * This structure exists for each remote FC port that a LLDD notifies + * the subsystem of. A remote FC port may or may not be a SCSI Target, + * also be a SCSI initiator, IP endpoint, etc. As such, the remote + * port is considered a separate entity, independent of "role" (such + * as scsi target). + * + * -- + * + * Attributes are based on HBAAPI V2.0 definitions. Only those + * attributes that are determinable by the local port (aka Host) + * are contained. + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after successfully calling + * fc_remote_port_add(). The transport fully manages all get functions + * w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +struct fc_rport { /* aka fc_starget_attrs */ + /* Fixed Attributes */ + u32 maxframe_size; + u32 supported_classes; + + /* Dynamic Attributes */ + u32 dev_loss_tmo; /* Remote Port loss timeout in seconds. */ + + /* Private (Transport-managed) Attributes */ + u64 node_name; + u64 port_name; + u32 port_id; + u32 roles; + enum fc_port_state port_state; /* Will only be ONLINE or UNKNOWN */ + u32 scsi_target_id; + u32 fast_io_fail_tmo; + + /* exported data */ + void *dd_data; /* Used for driver-specific storage */ + + /* internal data */ + unsigned int channel; + u32 number; + u8 flags; + struct list_head peers; + struct device dev; + struct delayed_work dev_loss_work; + struct work_struct scan_work; + struct delayed_work fail_io_work; + struct work_struct stgt_delete_work; + struct work_struct rport_delete_work; +} __attribute__((aligned(sizeof(unsigned long)))); + +/* bit field values for struct fc_rport "flags" field: */ +#define FC_RPORT_DEVLOSS_PENDING 0x01 +#define FC_RPORT_SCAN_PENDING 0x02 +#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x04 +#define FC_RPORT_DEVLOSS_CALLBK_DONE 0x08 + +#define dev_to_rport(d) \ + container_of(d, struct fc_rport, dev) +#define transport_class_to_rport(dev) \ + dev_to_rport(dev->parent) +#define rport_to_shost(r) \ + dev_to_shost(r->dev.parent) + +/* + * FC SCSI Target Attributes + * + * The SCSI Target is considered an extention of a remote port (as + * a remote port can be more than a SCSI Target). Within the scsi + * subsystem, we leave the Target as a separate entity. Doing so + * provides backward compatibility with prior FC transport api's, + * and lets remote ports be handled entirely within the FC transport + * and independently from the scsi subsystem. The drawback is that + * some data will be duplicated. + */ + +struct fc_starget_attrs { /* aka fc_target_attrs */ + /* Dynamic Attributes */ + u64 node_name; + u64 port_name; + u32 port_id; +}; + +#define fc_starget_node_name(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->node_name) +#define fc_starget_port_name(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->port_name) +#define fc_starget_port_id(x) \ + (((struct fc_starget_attrs *)&(x)->starget_data)->port_id) + +#define starget_to_rport(s) \ + scsi_is_fc_rport(s->dev.parent) ? dev_to_rport(s->dev.parent) : NULL + + +/* + * FC Local Port (Host) Statistics + */ + +/* FC Statistics - Following FC HBAAPI v2.0 guidelines */ +struct fc_host_statistics { + /* port statistics */ + u64 seconds_since_last_reset; + u64 tx_frames; + u64 tx_words; + u64 rx_frames; + u64 rx_words; + u64 lip_count; + u64 nos_count; + u64 error_frames; + u64 dumped_frames; + u64 link_failure_count; + u64 loss_of_sync_count; + u64 loss_of_signal_count; + u64 prim_seq_protocol_err_count; + u64 invalid_tx_word_count; + u64 invalid_crc_count; + + /* fc4 statistics (only FCP supported currently) */ + u64 fcp_input_requests; + u64 fcp_output_requests; + u64 fcp_control_requests; + u64 fcp_input_megabytes; + u64 fcp_output_megabytes; +}; + + +/* + * FC Event Codes - Polled and Async, following FC HBAAPI v2.0 guidelines + */ + +/* + * fc_host_event_code: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_host_event_code { + FCH_EVT_LIP = 0x1, + FCH_EVT_LINKUP = 0x2, + FCH_EVT_LINKDOWN = 0x3, + FCH_EVT_LIPRESET = 0x4, + FCH_EVT_RSCN = 0x5, + FCH_EVT_ADAPTER_CHANGE = 0x103, + FCH_EVT_PORT_UNKNOWN = 0x200, + FCH_EVT_PORT_OFFLINE = 0x201, + FCH_EVT_PORT_ONLINE = 0x202, + FCH_EVT_PORT_FABRIC = 0x204, + FCH_EVT_LINK_UNKNOWN = 0x500, + FCH_EVT_VENDOR_UNIQUE = 0xffff, +}; + + +/* + * FC Local Port (Host) Attributes + * + * Attributes are based on HBAAPI V2.0 definitions. + * Note: OSDeviceName is determined by user-space library + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after successfully calling scsi_add_host(). + * The transport fully manages all get functions w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +#define FC_FC4_LIST_SIZE 32 +#define FC_SYMBOLIC_NAME_SIZE 256 +#define FC_VERSION_STRING_SIZE 64 +#define FC_SERIAL_NUMBER_SIZE 80 + +struct fc_host_attrs { + /* Fixed Attributes */ + u64 node_name; + u64 port_name; + u64 permanent_port_name; + u32 supported_classes; + u8 supported_fc4s[FC_FC4_LIST_SIZE]; + u32 supported_speeds; + u32 maxframe_size; + u16 max_npiv_vports; + char serial_number[FC_SERIAL_NUMBER_SIZE]; + + /* Dynamic Attributes */ + u32 port_id; + enum fc_port_type port_type; + enum fc_port_state port_state; + u8 active_fc4s[FC_FC4_LIST_SIZE]; + u32 speed; + u64 fabric_name; + char symbolic_name[FC_SYMBOLIC_NAME_SIZE]; + char system_hostname[FC_SYMBOLIC_NAME_SIZE]; + + /* Private (Transport-managed) Attributes */ + enum fc_tgtid_binding_type tgtid_bind_type; + + /* internal data */ + struct list_head rports; + struct list_head rport_bindings; + struct list_head vports; + u32 next_rport_number; + u32 next_target_id; + u32 next_vport_number; + u16 npiv_vports_inuse; + + /* work queues for rport state manipulation */ + char work_q_name[20]; + struct workqueue_struct *work_q; + char devloss_work_q_name[20]; + struct workqueue_struct *devloss_work_q; +}; + +#define shost_to_fc_host(x) \ + ((struct fc_host_attrs *)(x)->shost_data) + +#define fc_host_node_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->node_name) +#define fc_host_port_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_name) +#define fc_host_permanent_port_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->permanent_port_name) +#define fc_host_supported_classes(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_classes) +#define fc_host_supported_fc4s(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_fc4s) +#define fc_host_supported_speeds(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds) +#define fc_host_maxframe_size(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size) +#define fc_host_max_npiv_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports) +#define fc_host_serial_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->serial_number) +#define fc_host_port_id(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_id) +#define fc_host_port_type(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_type) +#define fc_host_port_state(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->port_state) +#define fc_host_active_fc4s(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->active_fc4s) +#define fc_host_speed(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->speed) +#define fc_host_fabric_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->fabric_name) +#define fc_host_symbolic_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->symbolic_name) +#define fc_host_system_hostname(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->system_hostname) +#define fc_host_tgtid_bind_type(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->tgtid_bind_type) +#define fc_host_rports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->rports) +#define fc_host_rport_bindings(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings) +#define fc_host_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->vports) +#define fc_host_next_rport_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) +#define fc_host_next_target_id(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) +#define fc_host_next_vport_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_vport_number) +#define fc_host_npiv_vports_inuse(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse) +#define fc_host_work_q_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->work_q_name) +#define fc_host_work_q(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->work_q) +#define fc_host_devloss_work_q_name(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q_name) +#define fc_host_devloss_work_q(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q) + + +/* The functions by which the transport class and the driver communicate */ +struct fc_function_template { + void (*get_rport_dev_loss_tmo)(struct fc_rport *); + void (*set_rport_dev_loss_tmo)(struct fc_rport *, u32); + + void (*get_starget_node_name)(struct scsi_target *); + void (*get_starget_port_name)(struct scsi_target *); + void (*get_starget_port_id)(struct scsi_target *); + + void (*get_host_port_id)(struct Scsi_Host *); + void (*get_host_port_type)(struct Scsi_Host *); + void (*get_host_port_state)(struct Scsi_Host *); + void (*get_host_active_fc4s)(struct Scsi_Host *); + void (*get_host_speed)(struct Scsi_Host *); + void (*get_host_fabric_name)(struct Scsi_Host *); + void (*get_host_symbolic_name)(struct Scsi_Host *); + void (*set_host_system_hostname)(struct Scsi_Host *); + + struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *); + void (*reset_fc_host_stats)(struct Scsi_Host *); + + int (*issue_fc_host_lip)(struct Scsi_Host *); + + void (*dev_loss_tmo_callbk)(struct fc_rport *); + void (*terminate_rport_io)(struct fc_rport *); + + void (*set_vport_symbolic_name)(struct fc_vport *); + int (*vport_create)(struct fc_vport *, bool); + int (*vport_disable)(struct fc_vport *, bool); + int (*vport_delete)(struct fc_vport *); + + /* target-mode drivers' functions */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + + /* allocation lengths for host-specific data */ + u32 dd_fcrport_size; + u32 dd_fcvport_size; + + /* + * The driver sets these to tell the transport class it + * wants the attributes displayed in sysfs. If the show_ flag + * is not set, the attribute will be private to the transport + * class + */ + + /* remote port fixed attributes */ + unsigned long show_rport_maxframe_size:1; + unsigned long show_rport_supported_classes:1; + unsigned long show_rport_dev_loss_tmo:1; + + /* + * target dynamic attributes + * These should all be "1" if the driver uses the remote port + * add/delete functions (so attributes reflect rport values). + */ + unsigned long show_starget_node_name:1; + unsigned long show_starget_port_name:1; + unsigned long show_starget_port_id:1; + + /* host fixed attributes */ + unsigned long show_host_node_name:1; + unsigned long show_host_port_name:1; + unsigned long show_host_permanent_port_name:1; + unsigned long show_host_supported_classes:1; + unsigned long show_host_supported_fc4s:1; + unsigned long show_host_supported_speeds:1; + unsigned long show_host_maxframe_size:1; + unsigned long show_host_serial_number:1; + /* host dynamic attributes */ + unsigned long show_host_port_id:1; + unsigned long show_host_port_type:1; + unsigned long show_host_port_state:1; + unsigned long show_host_active_fc4s:1; + unsigned long show_host_speed:1; + unsigned long show_host_fabric_name:1; + unsigned long show_host_symbolic_name:1; + unsigned long show_host_system_hostname:1; + + unsigned long disable_target_scan:1; +}; + + +/** + * fc_remote_port_chkready - called to validate the remote port state + * prior to initiating io to the port. + * + * Returns a scsi result code that can be returned by the LLDD. + * + * @rport: remote port to be checked + **/ +static inline int +fc_remote_port_chkready(struct fc_rport *rport) +{ + int result; + + switch (rport->port_state) { + case FC_PORTSTATE_ONLINE: + if (rport->roles & FC_PORT_ROLE_FCP_TARGET) + result = 0; + else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) + result = DID_TRANSPORT_DISRUPTED << 16; + else + result = DID_NO_CONNECT << 16; + break; + case FC_PORTSTATE_BLOCKED: + if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) + result = DID_TRANSPORT_FAILFAST << 16; + else + result = DID_TRANSPORT_DISRUPTED << 16; + break; + default: + result = DID_NO_CONNECT << 16; + break; + } + return result; +} + +static inline u64 wwn_to_u64(u8 *wwn) +{ + return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 | + (u64)wwn[2] << 40 | (u64)wwn[3] << 32 | + (u64)wwn[4] << 24 | (u64)wwn[5] << 16 | + (u64)wwn[6] << 8 | (u64)wwn[7]; +} + +static inline void u64_to_wwn(u64 inm, u8 *wwn) +{ + wwn[0] = (inm >> 56) & 0xff; + wwn[1] = (inm >> 48) & 0xff; + wwn[2] = (inm >> 40) & 0xff; + wwn[3] = (inm >> 32) & 0xff; + wwn[4] = (inm >> 24) & 0xff; + wwn[5] = (inm >> 16) & 0xff; + wwn[6] = (inm >> 8) & 0xff; + wwn[7] = inm & 0xff; +} + +/** + * fc_vport_set_state() - called to set a vport's state. Saves the old state, + * excepting the transitory states of initializing and sending the ELS + * traffic to instantiate the vport on the link. + * + * Assumes the driver has surrounded this with the proper locking to ensure + * a coherent state change. + * + * @vport: virtual port whose state is changing + * @new_state: new state + **/ +static inline void +fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state) +{ + if ((new_state != FC_VPORT_UNKNOWN) && + (new_state != FC_VPORT_INITIALIZING)) + vport->vport_last_state = vport->vport_state; + vport->vport_state = new_state; +} + + +struct scsi_transport_template *fc_attach_transport( + struct fc_function_template *); +void fc_release_transport(struct scsi_transport_template *); +void fc_remove_host(struct Scsi_Host *); +struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, + int channel, struct fc_rport_identifiers *ids); +void fc_remote_port_delete(struct fc_rport *rport); +void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles); +int scsi_is_fc_rport(const struct device *); +u32 fc_get_event_number(void); +void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, + enum fc_host_event_code event_code, u32 event_data); +void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, + u32 data_len, char * data_buf, u64 vendor_id); + /* Note: when specifying vendor_id to fc_host_post_vendor_event() + * be sure to read the Vendor Type and ID formatting requirements + * specified in scsi_netlink.h + */ +struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, + struct fc_vport_identifiers *); +int fc_vport_terminate(struct fc_vport *vport); + +#endif /* SCSI_TRANSPORT_FC_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport_iscsi.h b/libdde_linux26/contrib/include/scsi/scsi_transport_iscsi.h new file mode 100644 index 00000000..b50aabe2 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport_iscsi.h @@ -0,0 +1,255 @@ +/* + * iSCSI transport class definitions + * + * Copyright (C) IBM Corporation, 2004 + * Copyright (C) Mike Christie, 2004 - 2006 + * Copyright (C) Dmitry Yusupov, 2004 - 2005 + * Copyright (C) Alex Aizman, 2004 - 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef SCSI_TRANSPORT_ISCSI_H +#define SCSI_TRANSPORT_ISCSI_H + +#include <linux/device.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <scsi/iscsi_if.h> + +struct scsi_transport_template; +struct iscsi_transport; +struct iscsi_endpoint; +struct Scsi_Host; +struct iscsi_cls_conn; +struct iscsi_conn; +struct iscsi_task; +struct sockaddr; + +/** + * struct iscsi_transport - iSCSI Transport template + * + * @name: transport name + * @caps: iSCSI Data-Path capabilities + * @create_session: create new iSCSI session object + * @destroy_session: destroy existing iSCSI session object + * @create_conn: create new iSCSI connection + * @bind_conn: associate this connection with existing iSCSI session + * and specified transport descriptor + * @destroy_conn: destroy inactive iSCSI connection + * @set_param: set iSCSI parameter. Return 0 on success, -ENODATA + * when param is not supported, and a -Exx value on other + * error. + * @get_param get iSCSI parameter. Must return number of bytes + * copied to buffer on success, -ENODATA when param + * is not supported, and a -Exx value on other error + * @start_conn: set connection to be operational + * @stop_conn: suspend/recover/terminate connection + * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. + * @session_recovery_timedout: notify LLD a block during recovery timed out + * @init_task: Initialize a iscsi_task and any internal structs. + * When offloading the data path, this is called from + * queuecommand with the session lock, or from the + * iscsi_conn_send_pdu context with the session lock. + * When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @xmit_task Requests LLD to transfer cmd task. Returns 0 or the + * the number of bytes transferred on success, and -Exyz + * value on error. When offloading the data path, this + * is called from queuecommand with the session lock, or + * from the iscsi_conn_send_pdu context with the session + * lock. When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @cleanup_task: requests LLD to fail task. Called with session lock + * and after the connection has been suspended and + * terminated during recovery. If called + * from abort task then connection is not suspended + * or terminated but sk_callback_lock is held + * + * Template API provided by iSCSI Transport + */ +struct iscsi_transport { + struct module *owner; + char *name; + unsigned int caps; + /* LLD sets this to indicate what values it can export to sysfs */ + uint64_t param_mask; + uint64_t host_param_mask; + struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep, + uint16_t cmds_max, uint16_t qdepth, + uint32_t sn, uint32_t *hn); + void (*destroy_session) (struct iscsi_cls_session *session); + struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, + uint32_t cid); + int (*bind_conn) (struct iscsi_cls_session *session, + struct iscsi_cls_conn *cls_conn, + uint64_t transport_eph, int is_leading); + int (*start_conn) (struct iscsi_cls_conn *conn); + void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); + void (*destroy_conn) (struct iscsi_cls_conn *conn); + int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, + char *buf, int buflen); + int (*get_conn_param) (struct iscsi_cls_conn *conn, + enum iscsi_param param, char *buf); + int (*get_session_param) (struct iscsi_cls_session *session, + enum iscsi_param param, char *buf); + int (*get_host_param) (struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf); + int (*set_host_param) (struct Scsi_Host *shost, + enum iscsi_host_param param, char *buf, + int buflen); + int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); + void (*get_stats) (struct iscsi_cls_conn *conn, + struct iscsi_stats *stats); + + int (*init_task) (struct iscsi_task *task); + int (*xmit_task) (struct iscsi_task *task); + void (*cleanup_task) (struct iscsi_task *task); + + int (*alloc_pdu) (struct iscsi_task *task, uint8_t opcode); + int (*xmit_pdu) (struct iscsi_task *task); + int (*init_pdu) (struct iscsi_task *task, unsigned int offset, + unsigned int count); + void (*parse_pdu_itt) (struct iscsi_conn *conn, itt_t itt, + int *index, int *age); + + void (*session_recovery_timedout) (struct iscsi_cls_session *session); + struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, + int non_blocking); + int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms); + void (*ep_disconnect) (struct iscsi_endpoint *ep); + int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type, + uint32_t enable, struct sockaddr *dst_addr); +}; + +/* + * transport registration upcalls + */ +extern struct scsi_transport_template *iscsi_register_transport(struct iscsi_transport *tt); +extern int iscsi_unregister_transport(struct iscsi_transport *tt); + +/* + * control plane upcalls + */ +extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn, + enum iscsi_err error); +extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size); + +struct iscsi_cls_conn { + struct list_head conn_list; /* item in connlist */ + void *dd_data; /* LLD private data */ + struct iscsi_transport *transport; + uint32_t cid; /* connection id */ + + int active; /* must be accessed with the connlock */ + struct device dev; /* sysfs transport/container device */ +}; + +#define iscsi_dev_to_conn(_dev) \ + container_of(_dev, struct iscsi_cls_conn, dev) + +#define iscsi_conn_to_session(_conn) \ + iscsi_dev_to_session(_conn->dev.parent) + +/* iscsi class session state */ +enum { + ISCSI_SESSION_LOGGED_IN, + ISCSI_SESSION_FAILED, + ISCSI_SESSION_FREE, +}; + +#define ISCSI_MAX_TARGET -1 + +struct iscsi_cls_session { + struct list_head sess_list; /* item in session_list */ + struct iscsi_transport *transport; + spinlock_t lock; + struct work_struct block_work; + struct work_struct unblock_work; + struct work_struct scan_work; + struct work_struct unbind_work; + + /* recovery fields */ + int recovery_tmo; + struct delayed_work recovery_work; + + unsigned int target_id; + + int state; + int sid; /* session id */ + void *dd_data; /* LLD private data */ + struct device dev; /* sysfs transport/container device */ +}; + +#define iscsi_dev_to_session(_dev) \ + container_of(_dev, struct iscsi_cls_session, dev) + +#define iscsi_session_to_shost(_session) \ + dev_to_shost(_session->dev.parent) + +#define starget_to_session(_stgt) \ + iscsi_dev_to_session(_stgt->dev.parent) + +struct iscsi_cls_host { + atomic_t nr_scans; + struct mutex mutex; + struct workqueue_struct *scan_workq; + char scan_workq_name[20]; +}; + +extern void iscsi_host_for_each_session(struct Scsi_Host *shost, + void (*fn)(struct iscsi_cls_session *)); + +struct iscsi_endpoint { + void *dd_data; /* LLD private data */ + struct device dev; + uint64_t id; +}; + +/* + * session and connection functions that can be used by HW iSCSI LLDs + */ +#define iscsi_cls_session_printk(prefix, _cls_session, fmt, a...) \ + dev_printk(prefix, &(_cls_session)->dev, fmt, ##a) + +#define iscsi_cls_conn_printk(prefix, _cls_conn, fmt, a...) \ + dev_printk(prefix, &(_cls_conn)->dev, fmt, ##a) + +extern int iscsi_session_chkready(struct iscsi_cls_session *session); +extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, + struct iscsi_transport *transport, int dd_size); +extern int iscsi_add_session(struct iscsi_cls_session *session, + unsigned int target_id); +extern int iscsi_session_event(struct iscsi_cls_session *session, + enum iscsi_uevent_e event); +extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, + struct iscsi_transport *t, + int dd_size, + unsigned int target_id); +extern void iscsi_remove_session(struct iscsi_cls_session *session); +extern void iscsi_free_session(struct iscsi_cls_session *session); +extern int iscsi_destroy_session(struct iscsi_cls_session *session); +extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, + int dd_size, uint32_t cid); +extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); +extern void iscsi_unblock_session(struct iscsi_cls_session *session); +extern void iscsi_block_session(struct iscsi_cls_session *session); +extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time); +extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size); +extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep); +extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle); + +#endif diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport_sas.h b/libdde_linux26/contrib/include/scsi/scsi_transport_sas.h new file mode 100644 index 00000000..61ad3594 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport_sas.h @@ -0,0 +1,220 @@ +#ifndef SCSI_TRANSPORT_SAS_H +#define SCSI_TRANSPORT_SAS_H + +#include <linux/transport_class.h> +#include <linux/types.h> +#include <linux/mutex.h> +#include <scsi/sas.h> + +struct scsi_transport_template; +struct sas_rphy; +struct request; + +enum sas_device_type { + SAS_PHY_UNUSED = 0, + SAS_END_DEVICE = 1, + SAS_EDGE_EXPANDER_DEVICE = 2, + SAS_FANOUT_EXPANDER_DEVICE = 3, +}; + +static inline int sas_protocol_ata(enum sas_protocol proto) +{ + return ((proto & SAS_PROTOCOL_SATA) || + (proto & SAS_PROTOCOL_STP))? 1 : 0; +} + +enum sas_linkrate { + /* These Values are defined in the SAS standard */ + SAS_LINK_RATE_UNKNOWN = 0, + SAS_PHY_DISABLED = 1, + SAS_PHY_RESET_PROBLEM = 2, + SAS_SATA_SPINUP_HOLD = 3, + SAS_SATA_PORT_SELECTOR = 4, + SAS_PHY_RESET_IN_PROGRESS = 5, + SAS_LINK_RATE_1_5_GBPS = 8, + SAS_LINK_RATE_G1 = SAS_LINK_RATE_1_5_GBPS, + SAS_LINK_RATE_3_0_GBPS = 9, + SAS_LINK_RATE_G2 = SAS_LINK_RATE_3_0_GBPS, + SAS_LINK_RATE_6_0_GBPS = 10, + /* These are virtual to the transport class and may never + * be signalled normally since the standard defined field + * is only 4 bits */ + SAS_LINK_RATE_FAILED = 0x10, + SAS_PHY_VIRTUAL = 0x11, +}; + +struct sas_identify { + enum sas_device_type device_type; + enum sas_protocol initiator_port_protocols; + enum sas_protocol target_port_protocols; + u64 sas_address; + u8 phy_identifier; +}; + +struct sas_phy { + struct device dev; + int number; + int enabled; + + /* phy identification */ + struct sas_identify identify; + + /* phy attributes */ + enum sas_linkrate negotiated_linkrate; + enum sas_linkrate minimum_linkrate_hw; + enum sas_linkrate minimum_linkrate; + enum sas_linkrate maximum_linkrate_hw; + enum sas_linkrate maximum_linkrate; + + /* link error statistics */ + u32 invalid_dword_count; + u32 running_disparity_error_count; + u32 loss_of_dword_sync_count; + u32 phy_reset_problem_count; + + /* for the list of phys belonging to a port */ + struct list_head port_siblings; + + struct work_struct reset_work; +}; + +#define dev_to_phy(d) \ + container_of((d), struct sas_phy, dev) +#define transport_class_to_phy(dev) \ + dev_to_phy((dev)->parent) +#define phy_to_shost(phy) \ + dev_to_shost((phy)->dev.parent) + +struct request_queue; +struct sas_rphy { + struct device dev; + struct sas_identify identify; + struct list_head list; + struct request_queue *q; + u32 scsi_target_id; +}; + +#define dev_to_rphy(d) \ + container_of((d), struct sas_rphy, dev) +#define transport_class_to_rphy(dev) \ + dev_to_rphy((dev)->parent) +#define rphy_to_shost(rphy) \ + dev_to_shost((rphy)->dev.parent) +#define target_to_rphy(targ) \ + dev_to_rphy((targ)->dev.parent) + +struct sas_end_device { + struct sas_rphy rphy; + /* flags */ + unsigned ready_led_meaning:1; + /* parameters */ + u16 I_T_nexus_loss_timeout; + u16 initiator_response_timeout; +}; +#define rphy_to_end_device(r) \ + container_of((r), struct sas_end_device, rphy) + +struct sas_expander_device { + int level; + int next_port_id; + + #define SAS_EXPANDER_VENDOR_ID_LEN 8 + char vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1]; + #define SAS_EXPANDER_PRODUCT_ID_LEN 16 + char product_id[SAS_EXPANDER_PRODUCT_ID_LEN+1]; + #define SAS_EXPANDER_PRODUCT_REV_LEN 4 + char product_rev[SAS_EXPANDER_PRODUCT_REV_LEN+1]; + #define SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN 8 + char component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN+1]; + u16 component_id; + u8 component_revision_id; + + struct sas_rphy rphy; + +}; +#define rphy_to_expander_device(r) \ + container_of((r), struct sas_expander_device, rphy) + +struct sas_port { + struct device dev; + + int port_identifier; + int num_phys; + /* port flags */ + unsigned int is_backlink:1; + + /* the other end of the link */ + struct sas_rphy *rphy; + + struct mutex phy_list_mutex; + struct list_head phy_list; +}; + +#define dev_to_sas_port(d) \ + container_of((d), struct sas_port, dev) +#define transport_class_to_sas_port(dev) \ + dev_to_sas_port((dev)->parent) + +struct sas_phy_linkrates { + enum sas_linkrate maximum_linkrate; + enum sas_linkrate minimum_linkrate; +}; + +/* The functions by which the transport class and the driver communicate */ +struct sas_function_template { + int (*get_linkerrors)(struct sas_phy *); + int (*get_enclosure_identifier)(struct sas_rphy *, u64 *); + int (*get_bay_identifier)(struct sas_rphy *); + int (*phy_reset)(struct sas_phy *, int); + int (*phy_enable)(struct sas_phy *, int); + int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); + int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); +}; + + +void sas_remove_children(struct device *); +extern void sas_remove_host(struct Scsi_Host *); + +extern struct sas_phy *sas_phy_alloc(struct device *, int); +extern void sas_phy_free(struct sas_phy *); +extern int sas_phy_add(struct sas_phy *); +extern void sas_phy_delete(struct sas_phy *); +extern int scsi_is_sas_phy(const struct device *); + +extern struct sas_rphy *sas_end_device_alloc(struct sas_port *); +extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); +void sas_rphy_free(struct sas_rphy *); +extern int sas_rphy_add(struct sas_rphy *); +extern void sas_rphy_remove(struct sas_rphy *); +extern void sas_rphy_delete(struct sas_rphy *); +extern int scsi_is_sas_rphy(const struct device *); + +struct sas_port *sas_port_alloc(struct device *, int); +struct sas_port *sas_port_alloc_num(struct device *); +int sas_port_add(struct sas_port *); +void sas_port_free(struct sas_port *); +void sas_port_delete(struct sas_port *); +void sas_port_add_phy(struct sas_port *, struct sas_phy *); +void sas_port_delete_phy(struct sas_port *, struct sas_phy *); +void sas_port_mark_backlink(struct sas_port *); +int scsi_is_sas_port(const struct device *); + +extern struct scsi_transport_template * +sas_attach_transport(struct sas_function_template *); +extern void sas_release_transport(struct scsi_transport_template *); +int sas_read_port_mode_page(struct scsi_device *); + +static inline int +scsi_is_sas_expander_device(struct device *dev) +{ + struct sas_rphy *rphy; + if (!scsi_is_sas_rphy(dev)) + return 0; + rphy = dev_to_rphy(dev); + return rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE || + rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE; +} + +#define scsi_is_sas_phy_local(phy) scsi_is_host_device((phy)->dev.parent) + +#endif /* SCSI_TRANSPORT_SAS_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport_spi.h b/libdde_linux26/contrib/include/scsi/scsi_transport_spi.h new file mode 100644 index 00000000..286e9628 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport_spi.h @@ -0,0 +1,157 @@ +/* + * Parallel SCSI (SPI) transport specific attributes exported to sysfs. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef SCSI_TRANSPORT_SPI_H +#define SCSI_TRANSPORT_SPI_H + +#include <linux/transport_class.h> +#include <linux/mutex.h> + +struct scsi_transport_template; +struct scsi_target; +struct scsi_device; +struct Scsi_Host; + +struct spi_transport_attrs { + int period; /* value in the PPR/SDTR command */ + int min_period; + int offset; + int max_offset; + unsigned int width:1; /* 0 - narrow, 1 - wide */ + unsigned int max_width:1; + unsigned int iu:1; /* Information Units enabled */ + unsigned int dt:1; /* DT clocking enabled */ + unsigned int qas:1; /* Quick Arbitration and Selection enabled */ + unsigned int wr_flow:1; /* Write Flow control enabled */ + unsigned int rd_strm:1; /* Read streaming enabled */ + unsigned int rti:1; /* Retain Training Information */ + unsigned int pcomp_en:1;/* Precompensation enabled */ + unsigned int hold_mcs:1;/* Hold Margin Control Settings */ + unsigned int initial_dv:1; /* DV done to this target yet */ + unsigned long flags; /* flags field for drivers to use */ + /* Device Properties fields */ + unsigned int support_sync:1; /* synchronous support */ + unsigned int support_wide:1; /* wide support */ + unsigned int support_dt:1; /* allows DT phases */ + unsigned int support_dt_only; /* disallows ST phases */ + unsigned int support_ius; /* support Information Units */ + unsigned int support_qas; /* supports quick arbitration and selection */ + /* Private Fields */ + unsigned int dv_pending:1; /* Internal flag: DV Requested */ + unsigned int dv_in_progress:1; /* Internal: DV started */ + struct mutex dv_mutex; /* semaphore to serialise dv */ +}; + +enum spi_signal_type { + SPI_SIGNAL_UNKNOWN = 1, + SPI_SIGNAL_SE, + SPI_SIGNAL_LVD, + SPI_SIGNAL_HVD, +}; + +struct spi_host_attrs { + enum spi_signal_type signalling; +}; + +/* accessor functions */ +#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) +#define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period) +#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) +#define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset) +#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) +#define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width) +#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) +#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) +#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) +#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->starget_data)->wr_flow) +#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rd_strm) +#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rti) +#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) +#define spi_hold_mcs(x) (((struct spi_transport_attrs *)&(x)->starget_data)->hold_mcs) +#define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) +#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) + +#define spi_support_sync(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_sync) +#define spi_support_wide(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_wide) +#define spi_support_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt) +#define spi_support_dt_only(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_dt_only) +#define spi_support_ius(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_ius) +#define spi_support_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_qas) + +#define spi_flags(x) (((struct spi_transport_attrs *)&(x)->starget_data)->flags) +#define spi_signalling(h) (((struct spi_host_attrs *)(h)->shost_data)->signalling) + + + +/* The functions by which the transport class and the driver communicate */ +struct spi_function_template { + void (*get_period)(struct scsi_target *); + void (*set_period)(struct scsi_target *, int); + void (*get_offset)(struct scsi_target *); + void (*set_offset)(struct scsi_target *, int); + void (*get_width)(struct scsi_target *); + void (*set_width)(struct scsi_target *, int); + void (*get_iu)(struct scsi_target *); + void (*set_iu)(struct scsi_target *, int); + void (*get_dt)(struct scsi_target *); + void (*set_dt)(struct scsi_target *, int); + void (*get_qas)(struct scsi_target *); + void (*set_qas)(struct scsi_target *, int); + void (*get_wr_flow)(struct scsi_target *); + void (*set_wr_flow)(struct scsi_target *, int); + void (*get_rd_strm)(struct scsi_target *); + void (*set_rd_strm)(struct scsi_target *, int); + void (*get_rti)(struct scsi_target *); + void (*set_rti)(struct scsi_target *, int); + void (*get_pcomp_en)(struct scsi_target *); + void (*set_pcomp_en)(struct scsi_target *, int); + void (*get_hold_mcs)(struct scsi_target *); + void (*set_hold_mcs)(struct scsi_target *, int); + void (*get_signalling)(struct Scsi_Host *); + void (*set_signalling)(struct Scsi_Host *, enum spi_signal_type); + int (*deny_binding)(struct scsi_target *); + /* The driver sets these to tell the transport class it + * wants the attributes displayed in sysfs. If the show_ flag + * is not set, the attribute will be private to the transport + * class */ + unsigned long show_period:1; + unsigned long show_offset:1; + unsigned long show_width:1; + unsigned long show_iu:1; + unsigned long show_dt:1; + unsigned long show_qas:1; + unsigned long show_wr_flow:1; + unsigned long show_rd_strm:1; + unsigned long show_rti:1; + unsigned long show_pcomp_en:1; + unsigned long show_hold_mcs:1; +}; + +struct scsi_transport_template *spi_attach_transport(struct spi_function_template *); +void spi_release_transport(struct scsi_transport_template *); +void spi_schedule_dv_device(struct scsi_device *); +void spi_dv_device(struct scsi_device *); +void spi_display_xfer_agreement(struct scsi_target *); +int spi_print_msg(const unsigned char *); +int spi_populate_width_msg(unsigned char *msg, int width); +int spi_populate_sync_msg(unsigned char *msg, int period, int offset); +int spi_populate_ppr_msg(unsigned char *msg, int period, int offset, int width, + int options); + +#endif /* SCSI_TRANSPORT_SPI_H */ diff --git a/libdde_linux26/contrib/include/scsi/scsi_transport_srp.h b/libdde_linux26/contrib/include/scsi/scsi_transport_srp.h new file mode 100644 index 00000000..9c60ca1c --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsi_transport_srp.h @@ -0,0 +1,39 @@ +#ifndef SCSI_TRANSPORT_SRP_H +#define SCSI_TRANSPORT_SRP_H + +#include <linux/transport_class.h> +#include <linux/types.h> +#include <linux/mutex.h> + +#define SRP_RPORT_ROLE_INITIATOR 0 +#define SRP_RPORT_ROLE_TARGET 1 + +struct srp_rport_identifiers { + u8 port_id[16]; + u8 roles; +}; + +struct srp_rport { + struct device dev; + + u8 port_id[16]; + u8 roles; +}; + +struct srp_function_template { + /* for target drivers */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); +}; + +extern struct scsi_transport_template * +srp_attach_transport(struct srp_function_template *); +extern void srp_release_transport(struct scsi_transport_template *); + +extern struct srp_rport *srp_rport_add(struct Scsi_Host *, + struct srp_rport_identifiers *); +extern void srp_rport_del(struct srp_rport *); + +extern void srp_remove_host(struct Scsi_Host *); + +#endif diff --git a/libdde_linux26/contrib/include/scsi/scsicam.h b/libdde_linux26/contrib/include/scsi/scsicam.h new file mode 100644 index 00000000..24ede474 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/scsicam.h @@ -0,0 +1,19 @@ +/* + * scsicam.h - SCSI CAM support functions, use for HDIO_GETGEO, etc. + * + * Copyright 1993, 1994 Drew Eckhardt + * Visionary Computing + * (Unix and Linux consulting and custom programming) + * drew@Colorado.EDU + * +1 (303) 786-7975 + * + * For more information, please consult the SCSI-CAM draft. + */ + +#ifndef SCSICAM_H +#define SCSICAM_H +extern int scsicam_bios_param (struct block_device *bdev, sector_t capacity, int *ip); +extern int scsi_partsize(unsigned char *buf, unsigned long capacity, + unsigned int *cyls, unsigned int *hds, unsigned int *secs); +extern unsigned char *scsi_bios_ptable(struct block_device *bdev); +#endif /* def SCSICAM_H */ diff --git a/libdde_linux26/contrib/include/scsi/sg.h b/libdde_linux26/contrib/include/scsi/sg.h new file mode 100644 index 00000000..934ae389 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/sg.h @@ -0,0 +1,308 @@ +#ifndef _SCSI_GENERIC_H +#define _SCSI_GENERIC_H + +#include <linux/compiler.h> + +/* + History: + Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user + process control of SCSI devices. + Development Sponsored by Killy Corp. NY NY +Original driver (sg.h): +* Copyright (C) 1992 Lawrence Foard +Version 2 and 3 extensions to driver: +* Copyright (C) 1998 - 2006 Douglas Gilbert + + Version: 3.5.34 (20060920) + This version is for 2.6 series kernels. + + For a full changelog see http://www.torque.net/sg + +Map of SG verions to the Linux kernels in which they appear: + ---------- ---------------------------------- + original all kernels < 2.2.6 + 2.1.40 2.2.20 + 3.0.x optional version 3 sg driver for 2.2 series + 3.1.17++ 2.4.0++ + 3.5.30++ 2.6.0++ + +Major new features in SG 3.x driver (cf SG 2.x drivers) + - SG_IO ioctl() combines function if write() and read() + - new interface (sg_io_hdr_t) but still supports old interface + - scatter/gather in user space, direct IO, and mmap supported + + The normal action of this driver is to use the adapter (HBA) driver to DMA + data into kernel buffers and then use the CPU to copy the data into the + user space (vice versa for writes). That is called "indirect" IO due to + the double handling of data. There are two methods offered to remove the + redundant copy: 1) direct IO and 2) using the mmap() system call to map + the reserve buffer (this driver has one reserve buffer per fd) into the + user space. Both have their advantages. + In terms of absolute speed mmap() is faster. If speed is not a concern, + indirect IO should be fine. Read the documentation for more information. + + ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or + 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed. + That attribute is 0 by default. ** + + Historical note: this SCSI pass-through driver has been known as "sg" for + a decade. In broader kernel discussions "sg" is used to refer to scatter + gather techniques. The context should clarify which "sg" is referred to. + + Documentation + ============= + A web site for the SG device driver can be found at: + http://www.torque.net/sg [alternatively check the MAINTAINERS file] + The documentation for the sg version 3 driver can be found at: + http://www.torque.net/sg/p/sg_v3_ho.html + This is a rendering from DocBook source [change the extension to "sgml" + or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). + The SG_IO ioctl is now found in other parts kernel (e.g. the block layer). + For more information see http://www.torque.net/sg/sg_io.html + + The older, version 2 documents discuss the original sg interface in detail: + http://www.torque.net/sg/p/scsi-generic.txt + http://www.torque.net/sg/p/scsi-generic_long.txt + Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt + + Utility and test programs are available at the sg web site. They are + packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils + (for the lk 2.2 series). +*/ + + +/* New interface introduced in the 3.x SG drivers follows */ + +typedef struct sg_iovec /* same structure as used by readv() Linux system */ +{ /* call. It defines one scatter-gather element. */ + void __user *iov_base; /* Starting address */ + size_t iov_len; /* Length in bytes */ +} sg_iovec_t; + + +typedef struct sg_io_hdr +{ + int interface_id; /* [i] 'S' for SCSI generic (required) */ + int dxfer_direction; /* [i] data transfer direction */ + unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ + unsigned char mx_sb_len; /* [i] max length to write to sbp */ + unsigned short iovec_count; /* [i] 0 implies no scatter gather */ + unsigned int dxfer_len; /* [i] byte count of data transfer */ + void __user *dxferp; /* [i], [*io] points to data transfer memory + or scatter gather list */ + unsigned char __user *cmdp; /* [i], [*i] points to command to perform */ + void __user *sbp; /* [i], [*o] points to sense_buffer memory */ + unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ + unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */ + int pack_id; /* [i->o] unused internally (normally) */ + void __user * usr_ptr; /* [i->o] unused internally */ + unsigned char status; /* [o] scsi status */ + unsigned char masked_status;/* [o] shifted, masked scsi status */ + unsigned char msg_status; /* [o] messaging level data (optional) */ + unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ + unsigned short host_status; /* [o] errors from host adapter */ + unsigned short driver_status;/* [o] errors from software driver */ + int resid; /* [o] dxfer_len - actual_transferred */ + unsigned int duration; /* [o] time taken by cmd (unit: millisec) */ + unsigned int info; /* [o] auxiliary information */ +} sg_io_hdr_t; /* 64 bytes long (on i386) */ + +#define SG_INTERFACE_ID_ORIG 'S' + +/* Use negative values to flag difference from original sg_header structure */ +#define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */ +#define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */ +#define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */ +#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the + additional property than during indirect + IO the user buffer is copied into the + kernel buffers before the transfer */ +#define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */ + +/* following flag values can be "or"-ed together */ +#define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */ +#define SG_FLAG_UNUSED_LUN_INHIBIT 2 /* default is overwrite lun in SCSI */ + /* command block (when <= SCSI_2) */ +#define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */ +#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */ + /* user space (debug indirect IO) */ + +/* following 'info' values are "or"-ed together */ +#define SG_INFO_OK_MASK 0x1 +#define SG_INFO_OK 0x0 /* no sense, host nor driver "noise" */ +#define SG_INFO_CHECK 0x1 /* something abnormal happened */ + +#define SG_INFO_DIRECT_IO_MASK 0x6 +#define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */ +#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */ +#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */ + + +typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */ + int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */ + int channel; + int scsi_id; /* scsi id of target device */ + int lun; + int scsi_type; /* TYPE_... defined in scsi/scsi.h */ + short h_cmd_per_lun;/* host (adapter) maximum commands per lun */ + short d_queue_depth;/* device (or adapter) maximum queue length */ + int unused[2]; /* probably find a good use, set 0 for now */ +} sg_scsi_id_t; /* 32 bytes long on i386 */ + +typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ + char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */ + char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */ + char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */ + char problem; /* 0 -> no problem detected, 1 -> error to report */ + int pack_id; /* pack_id associated with request */ + void __user *usr_ptr; /* user provided pointer (in new interface) */ + unsigned int duration; /* millisecs elapsed since written (req_state==1) + or request duration (req_state==2) */ + int unused; +} sg_req_info_t; /* 20 bytes long on i386 */ + + +/* IOCTLs: Those ioctls that are relevant to the SG 3.x drivers follow. + [Those that only apply to the SG 2.x drivers are at the end of the file.] + (_GET_s yield result via 'int *' 3rd argument unless otherwise indicated) */ + +#define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */ + +/* Used to configure SCSI command transformation layer for ATAPI devices */ +/* Only supported by the ide-scsi driver */ +#define SG_SET_TRANSFORM 0x2204 /* N.B. 3rd arg is not pointer but value: */ + /* 3rd arg = 0 to disable transform, 1 to enable it */ +#define SG_GET_TRANSFORM 0x2205 + +#define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */ +#define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */ + +/* The following ioctl has a 'sg_scsi_id_t *' object as its 3rd argument. */ +#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */ +/* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */ + +/* Override host setting and always DMA using low memory ( <16MB on i386) */ +#define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */ +#define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */ + +/* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which + tries to fetch a packet with a matching pack_id, waits, or returns EAGAIN. + If pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0 + then pack_id ignored by read() and oldest readable fetched. */ +#define SG_SET_FORCE_PACK_ID 0x227b +#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */ + +#define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */ + +/* Yields max scatter gather tablesize allowed by current host adapter */ +#define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */ + +#define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */ + +/* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */ +#define SG_SCSI_RESET 0x2284 +/* Associated values that can be given to SG_SCSI_RESET follow */ +#define SG_SCSI_RESET_NOTHING 0 +#define SG_SCSI_RESET_DEVICE 1 +#define SG_SCSI_RESET_BUS 2 +#define SG_SCSI_RESET_HOST 3 +#define SG_SCSI_RESET_TARGET 4 + +/* synchronous SCSI command ioctl, (only in version 3 interface) */ +#define SG_IO 0x2285 /* similar effect as write() followed by read() */ + +#define SG_GET_REQUEST_TABLE 0x2286 /* yields table of active requests */ + +/* How to treat EINTR during SG_IO ioctl(), only in SG 3.x series */ +#define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */ +#define SG_GET_KEEP_ORPHAN 0x2288 + +/* yields scsi midlevel's access_count for this SCSI device */ +#define SG_GET_ACCESS_COUNT 0x2289 + + +#define SG_SCATTER_SZ (8 * 4096) +/* Largest size (in bytes) a single scatter-gather list element can have. + The value used by the driver is 'max(SG_SCATTER_SZ, PAGE_SIZE)'. + This value should be a power of 2 (and may be rounded up internally). + If scatter-gather is not supported by adapter then this value is the + largest data block that can be read/written by a single scsi command. */ + +#define SG_DEFAULT_RETRIES 0 + +/* Defaults, commented if they differ from original sg driver */ +#define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */ +#define SG_DEF_FORCE_PACK_ID 0 +#define SG_DEF_KEEP_ORPHAN 0 +#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ /* load time option */ + +/* maximum outstanding requests, write() yields EDOM if exceeded */ +#define SG_MAX_QUEUE 16 + +#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */ + +/* Alternate style type names, "..._t" variants preferred */ +typedef struct sg_io_hdr Sg_io_hdr; +typedef struct sg_io_vec Sg_io_vec; +typedef struct sg_scsi_id Sg_scsi_id; +typedef struct sg_req_info Sg_req_info; + + +/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +/* The older SG interface based on the 'sg_header' structure follows. */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + +#define SG_MAX_SENSE 16 /* this only applies to the sg_header interface */ + +struct sg_header +{ + int pack_len; /* [o] reply_len (ie useless), ignored as input */ + int reply_len; /* [i] max length of expected reply (inc. sg_header) */ + int pack_id; /* [io] id number of packet (use ints >= 0) */ + int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */ + unsigned int twelve_byte:1; + /* [i] Force 12 byte command length for group 6 & 7 commands */ + unsigned int target_status:5; /* [o] scsi status from target */ + unsigned int host_status:8; /* [o] host status (see "DID" codes) */ + unsigned int driver_status:8; /* [o] driver status+suggestion */ + unsigned int other_flags:10; /* unused */ + unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases: + when target_status is CHECK_CONDITION or + when target_status is COMMAND_TERMINATED or + when (driver_status & DRIVER_SENSE) is true. */ +}; /* This structure is 36 bytes long on i386 */ + + +/* IOCTLs: The following are not required (or ignored) when the sg_io_hdr_t + interface is used. They are kept for backward compatibility with + the original and version 2 drivers. */ + +#define SG_SET_TIMEOUT 0x2201 /* unit: jiffies (10ms on i386) */ +#define SG_GET_TIMEOUT 0x2202 /* yield timeout as _return_ value */ + +/* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q. + Each time a sg_io_hdr_t object is seen on this file descriptor, this + command queuing flag is set on (overriding the previous setting). */ +#define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on) */ +#define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1 */ + +/* Turn on/off error sense trace (1 and 0 respectively, default is off). + Try using: "# cat /proc/scsi/sg/debug" instead in the v3 driver */ +#define SG_SET_DEBUG 0x227e /* 0 -> turn off debug */ + +#define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given + number on the next write() on this file descriptor */ + + +/* Defaults, commented if they differ from original sg driver */ +#ifdef __KERNEL__ +#define SG_DEFAULT_TIMEOUT_USER (60*USER_HZ) /* HZ == 'jiffies in 1 second' */ +#else +#define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */ +#endif + +#define SG_DEF_COMMAND_Q 0 /* command queuing is always on when + the new interface is used */ +#define SG_DEF_UNDERRUN_FLAG 0 + +#endif diff --git a/libdde_linux26/contrib/include/scsi/srp.h b/libdde_linux26/contrib/include/scsi/srp.h new file mode 100644 index 00000000..ad178fa7 --- /dev/null +++ b/libdde_linux26/contrib/include/scsi/srp.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2005 Cisco Systems. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * $Id$ + */ + +#ifndef SCSI_SRP_H +#define SCSI_SRP_H + +/* + * Structures and constants for the SCSI RDMA Protocol (SRP) as + * defined by the INCITS T10 committee. This file was written using + * draft Revision 16a of the SRP standard. + */ + +#include <linux/types.h> + +enum { + SRP_LOGIN_REQ = 0x00, + SRP_TSK_MGMT = 0x01, + SRP_CMD = 0x02, + SRP_I_LOGOUT = 0x03, + SRP_LOGIN_RSP = 0xc0, + SRP_RSP = 0xc1, + SRP_LOGIN_REJ = 0xc2, + SRP_T_LOGOUT = 0x80, + SRP_CRED_REQ = 0x81, + SRP_AER_REQ = 0x82, + SRP_CRED_RSP = 0x41, + SRP_AER_RSP = 0x42 +}; + +enum { + SRP_BUF_FORMAT_DIRECT = 1 << 1, + SRP_BUF_FORMAT_INDIRECT = 1 << 2 +}; + +enum { + SRP_NO_DATA_DESC = 0, + SRP_DATA_DESC_DIRECT = 1, + SRP_DATA_DESC_INDIRECT = 2 +}; + +enum { + SRP_TSK_ABORT_TASK = 0x01, + SRP_TSK_ABORT_TASK_SET = 0x02, + SRP_TSK_CLEAR_TASK_SET = 0x04, + SRP_TSK_LUN_RESET = 0x08, + SRP_TSK_CLEAR_ACA = 0x40 +}; + +enum srp_login_rej_reason { + SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL = 0x00010000, + SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES = 0x00010001, + SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002, + SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL = 0x00010003, + SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004, + SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED = 0x00010005, + SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED = 0x00010006 +}; + +enum { + SRP_REV10_IB_IO_CLASS = 0xff00, + SRP_REV16A_IB_IO_CLASS = 0x0100 +}; + +struct srp_direct_buf { + __be64 va; + __be32 key; + __be32 len; +}; + +/* + * We need the packed attribute because the SRP spec puts the list of + * descriptors at an offset of 20, which is not aligned to the size of + * struct srp_direct_buf. The whole structure must be packed to avoid + * having the 20-byte structure padded to 24 bytes on 64-bit architectures. + */ +struct srp_indirect_buf { + struct srp_direct_buf table_desc; + __be32 len; + struct srp_direct_buf desc_list[0]; +} __attribute__((packed)); + +enum { + SRP_MULTICHAN_SINGLE = 0, + SRP_MULTICHAN_MULTI = 1 +}; + +struct srp_login_req { + u8 opcode; + u8 reserved1[7]; + u64 tag; + __be32 req_it_iu_len; + u8 reserved2[4]; + __be16 req_buf_fmt; + u8 req_flags; + u8 reserved3[5]; + u8 initiator_port_id[16]; + u8 target_port_id[16]; +}; + +/* + * The SRP spec defines the size of the LOGIN_RSP structure to be 52 + * bytes, so it needs to be packed to avoid having it padded to 56 + * bytes on 64-bit architectures. + */ +struct srp_login_rsp { + u8 opcode; + u8 reserved1[3]; + __be32 req_lim_delta; + u64 tag; + __be32 max_it_iu_len; + __be32 max_ti_iu_len; + __be16 buf_fmt; + u8 rsp_flags; + u8 reserved2[25]; +} __attribute__((packed)); + +struct srp_login_rej { + u8 opcode; + u8 reserved1[3]; + __be32 reason; + u64 tag; + u8 reserved2[8]; + __be16 buf_fmt; + u8 reserved3[6]; +}; + +struct srp_i_logout { + u8 opcode; + u8 reserved[7]; + u64 tag; +}; + +struct srp_t_logout { + u8 opcode; + u8 sol_not; + u8 reserved[2]; + __be32 reason; + u64 tag; +}; + +/* + * We need the packed attribute because the SRP spec only aligns the + * 8-byte LUN field to 4 bytes. + */ +struct srp_tsk_mgmt { + u8 opcode; + u8 sol_not; + u8 reserved1[6]; + u64 tag; + u8 reserved2[4]; + __be64 lun __attribute__((packed)); + u8 reserved3[2]; + u8 tsk_mgmt_func; + u8 reserved4; + u64 task_tag; + u8 reserved5[8]; +}; + +/* + * We need the packed attribute because the SRP spec only aligns the + * 8-byte LUN field to 4 bytes. + */ +struct srp_cmd { + u8 opcode; + u8 sol_not; + u8 reserved1[3]; + u8 buf_fmt; + u8 data_out_desc_cnt; + u8 data_in_desc_cnt; + u64 tag; + u8 reserved2[4]; + __be64 lun __attribute__((packed)); + u8 reserved3; + u8 task_attr; + u8 reserved4; + u8 add_cdb_len; + u8 cdb[16]; + u8 add_data[0]; +}; + +enum { + SRP_RSP_FLAG_RSPVALID = 1 << 0, + SRP_RSP_FLAG_SNSVALID = 1 << 1, + SRP_RSP_FLAG_DOOVER = 1 << 2, + SRP_RSP_FLAG_DOUNDER = 1 << 3, + SRP_RSP_FLAG_DIOVER = 1 << 4, + SRP_RSP_FLAG_DIUNDER = 1 << 5 +}; + +/* + * The SRP spec defines the size of the RSP structure to be 36 bytes, + * so it needs to be packed to avoid having it padded to 40 bytes on + * 64-bit architectures. + */ +struct srp_rsp { + u8 opcode; + u8 sol_not; + u8 reserved1[2]; + __be32 req_lim_delta; + u64 tag; + u8 reserved2[2]; + u8 flags; + u8 status; + __be32 data_out_res_cnt; + __be32 data_in_res_cnt; + __be32 sense_data_len; + __be32 resp_data_len; + u8 data[0]; +} __attribute__((packed)); + +#endif /* SCSI_SRP_H */ |