brintos

brintos / linux-shallow public Read only

0
0
Text · 57.7 KiB · 3b89b5a Raw
2300 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * SBP2 target driver (SCSI over IEEE1394 in target mode)4 *5 * Copyright (C) 2011  Chris Boot <bootc@bootc.net>6 */7 8#define KMSG_COMPONENT "sbp_target"9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt10 11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/init.h>14#include <linux/types.h>15#include <linux/string.h>16#include <linux/configfs.h>17#include <linux/ctype.h>18#include <linux/delay.h>19#include <linux/firewire.h>20#include <linux/firewire-constants.h>21#include <scsi/scsi_proto.h>22#include <scsi/scsi_tcq.h>23#include <target/target_core_base.h>24#include <target/target_core_backend.h>25#include <target/target_core_fabric.h>26#include <linux/unaligned.h>27 28#include "sbp_target.h"29 30/* FireWire address region for management and command block address handlers */31static const struct fw_address_region sbp_register_region = {32	.start	= CSR_REGISTER_BASE + 0x10000,33	.end	= 0x1000000000000ULL,34};35 36static const u32 sbp_unit_directory_template[] = {37	0x1200609e, /* unit_specifier_id: NCITS/T10 */38	0x13010483, /* unit_sw_version: 1155D Rev 4 */39	0x3800609e, /* command_set_specifier_id: NCITS/T10 */40	0x390104d8, /* command_set: SPC-2 */41	0x3b000000, /* command_set_revision: 0 */42	0x3c000001, /* firmware_revision: 1 */43};44 45#define SESSION_MAINTENANCE_INTERVAL HZ46 47static atomic_t login_id = ATOMIC_INIT(0);48 49static void session_maintenance_work(struct work_struct *);50static int sbp_run_transaction(struct fw_card *, int, int, int, int,51		unsigned long long, void *, size_t);52 53static int read_peer_guid(u64 *guid, const struct sbp_management_request *req)54{55	int ret;56	__be32 high, low;57 58	ret = sbp_run_transaction(req->card, TCODE_READ_QUADLET_REQUEST,59			req->node_addr, req->generation, req->speed,60			(CSR_REGISTER_BASE | CSR_CONFIG_ROM) + 3 * 4,61			&high, sizeof(high));62	if (ret != RCODE_COMPLETE)63		return ret;64 65	ret = sbp_run_transaction(req->card, TCODE_READ_QUADLET_REQUEST,66			req->node_addr, req->generation, req->speed,67			(CSR_REGISTER_BASE | CSR_CONFIG_ROM) + 4 * 4,68			&low, sizeof(low));69	if (ret != RCODE_COMPLETE)70		return ret;71 72	*guid = (u64)be32_to_cpu(high) << 32 | be32_to_cpu(low);73 74	return RCODE_COMPLETE;75}76 77static struct sbp_session *sbp_session_find_by_guid(78	struct sbp_tpg *tpg, u64 guid)79{80	struct se_session *se_sess;81	struct sbp_session *sess, *found = NULL;82 83	spin_lock_bh(&tpg->se_tpg.session_lock);84	list_for_each_entry(se_sess, &tpg->se_tpg.tpg_sess_list, sess_list) {85		sess = se_sess->fabric_sess_ptr;86		if (sess->guid == guid)87			found = sess;88	}89	spin_unlock_bh(&tpg->se_tpg.session_lock);90 91	return found;92}93 94static struct sbp_login_descriptor *sbp_login_find_by_lun(95		struct sbp_session *session, u32 unpacked_lun)96{97	struct sbp_login_descriptor *login, *found = NULL;98 99	spin_lock_bh(&session->lock);100	list_for_each_entry(login, &session->login_list, link) {101		if (login->login_lun == unpacked_lun)102			found = login;103	}104	spin_unlock_bh(&session->lock);105 106	return found;107}108 109static int sbp_login_count_all_by_lun(110		struct sbp_tpg *tpg,111		u32 unpacked_lun,112		int exclusive)113{114	struct se_session *se_sess;115	struct sbp_session *sess;116	struct sbp_login_descriptor *login;117	int count = 0;118 119	spin_lock_bh(&tpg->se_tpg.session_lock);120	list_for_each_entry(se_sess, &tpg->se_tpg.tpg_sess_list, sess_list) {121		sess = se_sess->fabric_sess_ptr;122 123		spin_lock_bh(&sess->lock);124		list_for_each_entry(login, &sess->login_list, link) {125			if (login->login_lun != unpacked_lun)126				continue;127 128			if (!exclusive || login->exclusive)129				count++;130		}131		spin_unlock_bh(&sess->lock);132	}133	spin_unlock_bh(&tpg->se_tpg.session_lock);134 135	return count;136}137 138static struct sbp_login_descriptor *sbp_login_find_by_id(139	struct sbp_tpg *tpg, int login_id)140{141	struct se_session *se_sess;142	struct sbp_session *sess;143	struct sbp_login_descriptor *login, *found = NULL;144 145	spin_lock_bh(&tpg->se_tpg.session_lock);146	list_for_each_entry(se_sess, &tpg->se_tpg.tpg_sess_list, sess_list) {147		sess = se_sess->fabric_sess_ptr;148 149		spin_lock_bh(&sess->lock);150		list_for_each_entry(login, &sess->login_list, link) {151			if (login->login_id == login_id)152				found = login;153		}154		spin_unlock_bh(&sess->lock);155	}156	spin_unlock_bh(&tpg->se_tpg.session_lock);157 158	return found;159}160 161static u32 sbp_get_lun_from_tpg(struct sbp_tpg *tpg, u32 login_lun, int *err)162{163	struct se_portal_group *se_tpg = &tpg->se_tpg;164	struct se_lun *se_lun;165 166	rcu_read_lock();167	hlist_for_each_entry_rcu(se_lun, &se_tpg->tpg_lun_hlist, link) {168		if (se_lun->unpacked_lun == login_lun) {169			rcu_read_unlock();170			*err = 0;171			return login_lun;172		}173	}174	rcu_read_unlock();175 176	*err = -ENODEV;177	return login_lun;178}179 180static struct sbp_session *sbp_session_create(181		struct sbp_tpg *tpg,182		u64 guid)183{184	struct sbp_session *sess;185	int ret;186	char guid_str[17];187 188	snprintf(guid_str, sizeof(guid_str), "%016llx", guid);189 190	sess = kmalloc(sizeof(*sess), GFP_KERNEL);191	if (!sess)192		return ERR_PTR(-ENOMEM);193 194	spin_lock_init(&sess->lock);195	INIT_LIST_HEAD(&sess->login_list);196	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);197	sess->guid = guid;198 199	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,200					     sizeof(struct sbp_target_request),201					     TARGET_PROT_NORMAL, guid_str,202					     sess, NULL);203	if (IS_ERR(sess->se_sess)) {204		pr_err("failed to init se_session\n");205		ret = PTR_ERR(sess->se_sess);206		kfree(sess);207		return ERR_PTR(ret);208	}209 210	return sess;211}212 213static void sbp_session_release(struct sbp_session *sess, bool cancel_work)214{215	spin_lock_bh(&sess->lock);216	if (!list_empty(&sess->login_list)) {217		spin_unlock_bh(&sess->lock);218		return;219	}220	spin_unlock_bh(&sess->lock);221 222	if (cancel_work)223		cancel_delayed_work_sync(&sess->maint_work);224 225	target_remove_session(sess->se_sess);226 227	if (sess->card)228		fw_card_put(sess->card);229 230	kfree(sess);231}232 233static void sbp_target_agent_unregister(struct sbp_target_agent *);234 235static void sbp_login_release(struct sbp_login_descriptor *login,236	bool cancel_work)237{238	struct sbp_session *sess = login->sess;239 240	/* FIXME: abort/wait on tasks */241 242	sbp_target_agent_unregister(login->tgt_agt);243 244	if (sess) {245		spin_lock_bh(&sess->lock);246		list_del(&login->link);247		spin_unlock_bh(&sess->lock);248 249		sbp_session_release(sess, cancel_work);250	}251 252	kfree(login);253}254 255static struct sbp_target_agent *sbp_target_agent_register(256	struct sbp_login_descriptor *);257 258static void sbp_management_request_login(259	struct sbp_management_agent *agent, struct sbp_management_request *req,260	int *status_data_size)261{262	struct sbp_tport *tport = agent->tport;263	struct sbp_tpg *tpg = tport->tpg;264	struct sbp_session *sess;265	struct sbp_login_descriptor *login;266	struct sbp_login_response_block *response;267	u64 guid;268	u32 unpacked_lun;269	int login_response_len, ret;270 271	unpacked_lun = sbp_get_lun_from_tpg(tpg,272			LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)), &ret);273	if (ret) {274		pr_notice("login to unknown LUN: %d\n",275			LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)));276 277		req->status.status = cpu_to_be32(278			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |279			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_LUN_NOTSUPP));280		return;281	}282 283	ret = read_peer_guid(&guid, req);284	if (ret != RCODE_COMPLETE) {285		pr_warn("failed to read peer GUID: %d\n", ret);286 287		req->status.status = cpu_to_be32(288			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |289			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));290		return;291	}292 293	pr_notice("mgt_agent LOGIN to LUN %d from %016llx\n",294		unpacked_lun, guid);295 296	sess = sbp_session_find_by_guid(tpg, guid);297	if (sess) {298		login = sbp_login_find_by_lun(sess, unpacked_lun);299		if (login) {300			pr_notice("initiator already logged-in\n");301 302			/*303			 * SBP-2 R4 says we should return access denied, but304			 * that can confuse initiators. Instead we need to305			 * treat this like a reconnect, but send the login306			 * response block like a fresh login.307			 *308			 * This is required particularly in the case of Apple309			 * devices booting off the FireWire target, where310			 * the firmware has an active login to the target. When311			 * the OS takes control of the session it issues its own312			 * LOGIN rather than a RECONNECT. To avoid the machine313			 * waiting until the reconnect_hold expires, we can skip314			 * the ACCESS_DENIED errors to speed things up.315			 */316 317			goto already_logged_in;318		}319	}320 321	/*322	 * check exclusive bit in login request323	 * reject with access_denied if any logins present324	 */325	if (LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)) &&326			sbp_login_count_all_by_lun(tpg, unpacked_lun, 0)) {327		pr_warn("refusing exclusive login with other active logins\n");328 329		req->status.status = cpu_to_be32(330			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |331			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_ACCESS_DENIED));332		return;333	}334 335	/*336	 * check exclusive bit in any existing login descriptor337	 * reject with access_denied if any exclusive logins present338	 */339	if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 1)) {340		pr_warn("refusing login while another exclusive login present\n");341 342		req->status.status = cpu_to_be32(343			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |344			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_ACCESS_DENIED));345		return;346	}347 348	/*349	 * check we haven't exceeded the number of allowed logins350	 * reject with resources_unavailable if we have351	 */352	if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 0) >=353			tport->max_logins_per_lun) {354		pr_warn("max number of logins reached\n");355 356		req->status.status = cpu_to_be32(357			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |358			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_RESOURCES_UNAVAIL));359		return;360	}361 362	if (!sess) {363		sess = sbp_session_create(tpg, guid);364		if (IS_ERR(sess)) {365			switch (PTR_ERR(sess)) {366			case -EPERM:367				ret = SBP_STATUS_ACCESS_DENIED;368				break;369			default:370				ret = SBP_STATUS_RESOURCES_UNAVAIL;371				break;372			}373 374			req->status.status = cpu_to_be32(375				STATUS_BLOCK_RESP(376					STATUS_RESP_REQUEST_COMPLETE) |377				STATUS_BLOCK_SBP_STATUS(ret));378			return;379		}380 381		sess->node_id = req->node_addr;382		sess->card = fw_card_get(req->card);383		sess->generation = req->generation;384		sess->speed = req->speed;385 386		schedule_delayed_work(&sess->maint_work,387				SESSION_MAINTENANCE_INTERVAL);388	}389 390	/* only take the latest reconnect_hold into account */391	sess->reconnect_hold = min(392		1 << LOGIN_ORB_RECONNECT(be32_to_cpu(req->orb.misc)),393		tport->max_reconnect_timeout) - 1;394 395	login = kmalloc(sizeof(*login), GFP_KERNEL);396	if (!login) {397		pr_err("failed to allocate login descriptor\n");398 399		sbp_session_release(sess, true);400 401		req->status.status = cpu_to_be32(402			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |403			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_RESOURCES_UNAVAIL));404		return;405	}406 407	login->sess = sess;408	login->login_lun = unpacked_lun;409	login->status_fifo_addr = sbp2_pointer_to_addr(&req->orb.status_fifo);410	login->exclusive = LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc));411	login->login_id = atomic_inc_return(&login_id);412 413	login->tgt_agt = sbp_target_agent_register(login);414	if (IS_ERR(login->tgt_agt)) {415		ret = PTR_ERR(login->tgt_agt);416		pr_err("failed to map command block handler: %d\n", ret);417 418		sbp_session_release(sess, true);419		kfree(login);420 421		req->status.status = cpu_to_be32(422			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |423			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_RESOURCES_UNAVAIL));424		return;425	}426 427	spin_lock_bh(&sess->lock);428	list_add_tail(&login->link, &sess->login_list);429	spin_unlock_bh(&sess->lock);430 431already_logged_in:432	response = kzalloc(sizeof(*response), GFP_KERNEL);433	if (!response) {434		pr_err("failed to allocate login response block\n");435 436		sbp_login_release(login, true);437 438		req->status.status = cpu_to_be32(439			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |440			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_RESOURCES_UNAVAIL));441		return;442	}443 444	login_response_len = clamp_val(445			LOGIN_ORB_RESPONSE_LENGTH(be32_to_cpu(req->orb.length)),446			12, sizeof(*response));447	response->misc = cpu_to_be32(448		((login_response_len & 0xffff) << 16) |449		(login->login_id & 0xffff));450	response->reconnect_hold = cpu_to_be32(sess->reconnect_hold & 0xffff);451	addr_to_sbp2_pointer(login->tgt_agt->handler.offset,452		&response->command_block_agent);453 454	ret = sbp_run_transaction(sess->card, TCODE_WRITE_BLOCK_REQUEST,455		sess->node_id, sess->generation, sess->speed,456		sbp2_pointer_to_addr(&req->orb.ptr2), response,457		login_response_len);458	if (ret != RCODE_COMPLETE) {459		pr_debug("failed to write login response block: %x\n", ret);460 461		kfree(response);462		sbp_login_release(login, true);463 464		req->status.status = cpu_to_be32(465			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |466			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));467		return;468	}469 470	kfree(response);471 472	req->status.status = cpu_to_be32(473		STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |474		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_OK));475}476 477static void sbp_management_request_query_logins(478	struct sbp_management_agent *agent, struct sbp_management_request *req,479	int *status_data_size)480{481	pr_notice("QUERY LOGINS not implemented\n");482	/* FIXME: implement */483 484	req->status.status = cpu_to_be32(485		STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |486		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));487}488 489static void sbp_management_request_reconnect(490	struct sbp_management_agent *agent, struct sbp_management_request *req,491	int *status_data_size)492{493	struct sbp_tport *tport = agent->tport;494	struct sbp_tpg *tpg = tport->tpg;495	int ret;496	u64 guid;497	struct sbp_login_descriptor *login;498 499	ret = read_peer_guid(&guid, req);500	if (ret != RCODE_COMPLETE) {501		pr_warn("failed to read peer GUID: %d\n", ret);502 503		req->status.status = cpu_to_be32(504			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |505			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));506		return;507	}508 509	pr_notice("mgt_agent RECONNECT from %016llx\n", guid);510 511	login = sbp_login_find_by_id(tpg,512		RECONNECT_ORB_LOGIN_ID(be32_to_cpu(req->orb.misc)));513 514	if (!login) {515		pr_err("mgt_agent RECONNECT unknown login ID\n");516 517		req->status.status = cpu_to_be32(518			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |519			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_ACCESS_DENIED));520		return;521	}522 523	if (login->sess->guid != guid) {524		pr_err("mgt_agent RECONNECT login GUID doesn't match\n");525 526		req->status.status = cpu_to_be32(527			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |528			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_ACCESS_DENIED));529		return;530	}531 532	spin_lock_bh(&login->sess->lock);533	if (login->sess->card)534		fw_card_put(login->sess->card);535 536	/* update the node details */537	login->sess->generation = req->generation;538	login->sess->node_id = req->node_addr;539	login->sess->card = fw_card_get(req->card);540	login->sess->speed = req->speed;541	spin_unlock_bh(&login->sess->lock);542 543	req->status.status = cpu_to_be32(544		STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |545		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_OK));546}547 548static void sbp_management_request_logout(549	struct sbp_management_agent *agent, struct sbp_management_request *req,550	int *status_data_size)551{552	struct sbp_tport *tport = agent->tport;553	struct sbp_tpg *tpg = tport->tpg;554	int id;555	struct sbp_login_descriptor *login;556 557	id = LOGOUT_ORB_LOGIN_ID(be32_to_cpu(req->orb.misc));558 559	login = sbp_login_find_by_id(tpg, id);560	if (!login) {561		pr_warn("cannot find login: %d\n", id);562 563		req->status.status = cpu_to_be32(564			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |565			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_LOGIN_ID_UNKNOWN));566		return;567	}568 569	pr_info("mgt_agent LOGOUT from LUN %d session %d\n",570		login->login_lun, login->login_id);571 572	if (req->node_addr != login->sess->node_id) {573		pr_warn("logout from different node ID\n");574 575		req->status.status = cpu_to_be32(576			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |577			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_ACCESS_DENIED));578		return;579	}580 581	sbp_login_release(login, true);582 583	req->status.status = cpu_to_be32(584		STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |585		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_OK));586}587 588static void session_check_for_reset(struct sbp_session *sess)589{590	bool card_valid = false;591 592	spin_lock_bh(&sess->lock);593 594	if (sess->card) {595		spin_lock_irq(&sess->card->lock);596		card_valid = (sess->card->local_node != NULL);597		spin_unlock_irq(&sess->card->lock);598 599		if (!card_valid) {600			fw_card_put(sess->card);601			sess->card = NULL;602		}603	}604 605	if (!card_valid || (sess->generation != sess->card->generation)) {606		pr_info("Waiting for reconnect from node: %016llx\n",607				sess->guid);608 609		sess->node_id = -1;610		sess->reconnect_expires = get_jiffies_64() +611			((sess->reconnect_hold + 1) * HZ);612	}613 614	spin_unlock_bh(&sess->lock);615}616 617static void session_reconnect_expired(struct sbp_session *sess)618{619	struct sbp_login_descriptor *login, *temp;620	LIST_HEAD(login_list);621 622	pr_info("Reconnect timer expired for node: %016llx\n", sess->guid);623 624	spin_lock_bh(&sess->lock);625	list_for_each_entry_safe(login, temp, &sess->login_list, link) {626		login->sess = NULL;627		list_move_tail(&login->link, &login_list);628	}629	spin_unlock_bh(&sess->lock);630 631	list_for_each_entry_safe(login, temp, &login_list, link) {632		list_del(&login->link);633		sbp_login_release(login, false);634	}635 636	sbp_session_release(sess, false);637}638 639static void session_maintenance_work(struct work_struct *work)640{641	struct sbp_session *sess = container_of(work, struct sbp_session,642			maint_work.work);643 644	/* could be called while tearing down the session */645	spin_lock_bh(&sess->lock);646	if (list_empty(&sess->login_list)) {647		spin_unlock_bh(&sess->lock);648		return;649	}650	spin_unlock_bh(&sess->lock);651 652	if (sess->node_id != -1) {653		/* check for bus reset and make node_id invalid */654		session_check_for_reset(sess);655 656		schedule_delayed_work(&sess->maint_work,657				SESSION_MAINTENANCE_INTERVAL);658	} else if (!time_after64(get_jiffies_64(), sess->reconnect_expires)) {659		/* still waiting for reconnect */660		schedule_delayed_work(&sess->maint_work,661				SESSION_MAINTENANCE_INTERVAL);662	} else {663		/* reconnect timeout has expired */664		session_reconnect_expired(sess);665	}666}667 668static int tgt_agent_rw_agent_state(struct fw_card *card, int tcode, void *data,669		struct sbp_target_agent *agent)670{671	int state;672 673	switch (tcode) {674	case TCODE_READ_QUADLET_REQUEST:675		pr_debug("tgt_agent AGENT_STATE READ\n");676 677		spin_lock_bh(&agent->lock);678		state = agent->state;679		spin_unlock_bh(&agent->lock);680 681		*(__be32 *)data = cpu_to_be32(state);682 683		return RCODE_COMPLETE;684 685	case TCODE_WRITE_QUADLET_REQUEST:686		/* ignored */687		return RCODE_COMPLETE;688 689	default:690		return RCODE_TYPE_ERROR;691	}692}693 694static int tgt_agent_rw_agent_reset(struct fw_card *card, int tcode, void *data,695		struct sbp_target_agent *agent)696{697	switch (tcode) {698	case TCODE_WRITE_QUADLET_REQUEST:699		pr_debug("tgt_agent AGENT_RESET\n");700		spin_lock_bh(&agent->lock);701		agent->state = AGENT_STATE_RESET;702		spin_unlock_bh(&agent->lock);703		return RCODE_COMPLETE;704 705	default:706		return RCODE_TYPE_ERROR;707	}708}709 710static int tgt_agent_rw_orb_pointer(struct fw_card *card, int tcode, void *data,711		struct sbp_target_agent *agent)712{713	struct sbp2_pointer *ptr = data;714 715	switch (tcode) {716	case TCODE_WRITE_BLOCK_REQUEST:717		spin_lock_bh(&agent->lock);718		if (agent->state != AGENT_STATE_SUSPENDED &&719				agent->state != AGENT_STATE_RESET) {720			spin_unlock_bh(&agent->lock);721			pr_notice("Ignoring ORB_POINTER write while active.\n");722			return RCODE_CONFLICT_ERROR;723		}724		agent->state = AGENT_STATE_ACTIVE;725		spin_unlock_bh(&agent->lock);726 727		agent->orb_pointer = sbp2_pointer_to_addr(ptr);728		agent->doorbell = false;729 730		pr_debug("tgt_agent ORB_POINTER write: 0x%llx\n",731				agent->orb_pointer);732 733		queue_work(system_unbound_wq, &agent->work);734 735		return RCODE_COMPLETE;736 737	case TCODE_READ_BLOCK_REQUEST:738		pr_debug("tgt_agent ORB_POINTER READ\n");739		spin_lock_bh(&agent->lock);740		addr_to_sbp2_pointer(agent->orb_pointer, ptr);741		spin_unlock_bh(&agent->lock);742		return RCODE_COMPLETE;743 744	default:745		return RCODE_TYPE_ERROR;746	}747}748 749static int tgt_agent_rw_doorbell(struct fw_card *card, int tcode, void *data,750		struct sbp_target_agent *agent)751{752	switch (tcode) {753	case TCODE_WRITE_QUADLET_REQUEST:754		spin_lock_bh(&agent->lock);755		if (agent->state != AGENT_STATE_SUSPENDED) {756			spin_unlock_bh(&agent->lock);757			pr_debug("Ignoring DOORBELL while active.\n");758			return RCODE_CONFLICT_ERROR;759		}760		agent->state = AGENT_STATE_ACTIVE;761		spin_unlock_bh(&agent->lock);762 763		agent->doorbell = true;764 765		pr_debug("tgt_agent DOORBELL\n");766 767		queue_work(system_unbound_wq, &agent->work);768 769		return RCODE_COMPLETE;770 771	case TCODE_READ_QUADLET_REQUEST:772		return RCODE_COMPLETE;773 774	default:775		return RCODE_TYPE_ERROR;776	}777}778 779static int tgt_agent_rw_unsolicited_status_enable(struct fw_card *card,780		int tcode, void *data, struct sbp_target_agent *agent)781{782	switch (tcode) {783	case TCODE_WRITE_QUADLET_REQUEST:784		pr_debug("tgt_agent UNSOLICITED_STATUS_ENABLE\n");785		/* ignored as we don't send unsolicited status */786		return RCODE_COMPLETE;787 788	case TCODE_READ_QUADLET_REQUEST:789		return RCODE_COMPLETE;790 791	default:792		return RCODE_TYPE_ERROR;793	}794}795 796static void tgt_agent_rw(struct fw_card *card, struct fw_request *request,797		int tcode, int destination, int source, int generation,798		unsigned long long offset, void *data, size_t length,799		void *callback_data)800{801	struct sbp_target_agent *agent = callback_data;802	struct sbp_session *sess = agent->login->sess;803	int sess_gen, sess_node, rcode;804 805	spin_lock_bh(&sess->lock);806	sess_gen = sess->generation;807	sess_node = sess->node_id;808	spin_unlock_bh(&sess->lock);809 810	if (generation != sess_gen) {811		pr_notice("ignoring request with wrong generation\n");812		rcode = RCODE_TYPE_ERROR;813		goto out;814	}815 816	if (source != sess_node) {817		pr_notice("ignoring request from foreign node (%x != %x)\n",818				source, sess_node);819		rcode = RCODE_TYPE_ERROR;820		goto out;821	}822 823	/* turn offset into the offset from the start of the block */824	offset -= agent->handler.offset;825 826	if (offset == 0x00 && length == 4) {827		/* AGENT_STATE */828		rcode = tgt_agent_rw_agent_state(card, tcode, data, agent);829	} else if (offset == 0x04 && length == 4) {830		/* AGENT_RESET */831		rcode = tgt_agent_rw_agent_reset(card, tcode, data, agent);832	} else if (offset == 0x08 && length == 8) {833		/* ORB_POINTER */834		rcode = tgt_agent_rw_orb_pointer(card, tcode, data, agent);835	} else if (offset == 0x10 && length == 4) {836		/* DOORBELL */837		rcode = tgt_agent_rw_doorbell(card, tcode, data, agent);838	} else if (offset == 0x14 && length == 4) {839		/* UNSOLICITED_STATUS_ENABLE */840		rcode = tgt_agent_rw_unsolicited_status_enable(card, tcode,841				data, agent);842	} else {843		rcode = RCODE_ADDRESS_ERROR;844	}845 846out:847	fw_send_response(card, request, rcode);848}849 850static void sbp_handle_command(struct sbp_target_request *);851static int sbp_send_status(struct sbp_target_request *);852static void sbp_free_request(struct sbp_target_request *);853 854static void tgt_agent_process_work(struct work_struct *work)855{856	struct sbp_target_request *req =857		container_of(work, struct sbp_target_request, work);858 859	pr_debug("tgt_orb ptr:0x%llx next_ORB:0x%llx data_descriptor:0x%llx misc:0x%x\n",860			req->orb_pointer,861			sbp2_pointer_to_addr(&req->orb.next_orb),862			sbp2_pointer_to_addr(&req->orb.data_descriptor),863			be32_to_cpu(req->orb.misc));864 865	if (req->orb_pointer >> 32)866		pr_debug("ORB with high bits set\n");867 868	switch (ORB_REQUEST_FORMAT(be32_to_cpu(req->orb.misc))) {869		case 0:/* Format specified by this standard */870			sbp_handle_command(req);871			return;872		case 1: /* Reserved for future standardization */873		case 2: /* Vendor-dependent */874			req->status.status |= cpu_to_be32(875					STATUS_BLOCK_RESP(876						STATUS_RESP_REQUEST_COMPLETE) |877					STATUS_BLOCK_DEAD(0) |878					STATUS_BLOCK_LEN(1) |879					STATUS_BLOCK_SBP_STATUS(880						SBP_STATUS_REQ_TYPE_NOTSUPP));881			sbp_send_status(req);882			return;883		case 3: /* Dummy ORB */884			req->status.status |= cpu_to_be32(885					STATUS_BLOCK_RESP(886						STATUS_RESP_REQUEST_COMPLETE) |887					STATUS_BLOCK_DEAD(0) |888					STATUS_BLOCK_LEN(1) |889					STATUS_BLOCK_SBP_STATUS(890						SBP_STATUS_DUMMY_ORB_COMPLETE));891			sbp_send_status(req);892			return;893		default:894			BUG();895	}896}897 898/* used to double-check we haven't been issued an AGENT_RESET */899static inline bool tgt_agent_check_active(struct sbp_target_agent *agent)900{901	bool active;902 903	spin_lock_bh(&agent->lock);904	active = (agent->state == AGENT_STATE_ACTIVE);905	spin_unlock_bh(&agent->lock);906 907	return active;908}909 910static struct sbp_target_request *sbp_mgt_get_req(struct sbp_session *sess,911	struct fw_card *card, u64 next_orb)912{913	struct se_session *se_sess = sess->se_sess;914	struct sbp_target_request *req;915	int tag, cpu;916 917	tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu);918	if (tag < 0)919		return ERR_PTR(-ENOMEM);920 921	req = &((struct sbp_target_request *)se_sess->sess_cmd_map)[tag];922	memset(req, 0, sizeof(*req));923	req->se_cmd.map_tag = tag;924	req->se_cmd.map_cpu = cpu;925	req->se_cmd.tag = next_orb;926 927	return req;928}929 930static void tgt_agent_fetch_work(struct work_struct *work)931{932	struct sbp_target_agent *agent =933		container_of(work, struct sbp_target_agent, work);934	struct sbp_session *sess = agent->login->sess;935	struct sbp_target_request *req;936	int ret;937	bool doorbell = agent->doorbell;938	u64 next_orb = agent->orb_pointer;939 940	while (next_orb && tgt_agent_check_active(agent)) {941		req = sbp_mgt_get_req(sess, sess->card, next_orb);942		if (IS_ERR(req)) {943			spin_lock_bh(&agent->lock);944			agent->state = AGENT_STATE_DEAD;945			spin_unlock_bh(&agent->lock);946			return;947		}948 949		req->login = agent->login;950		req->orb_pointer = next_orb;951 952		req->status.status = cpu_to_be32(STATUS_BLOCK_ORB_OFFSET_HIGH(953					req->orb_pointer >> 32));954		req->status.orb_low = cpu_to_be32(955				req->orb_pointer & 0xfffffffc);956 957		/* read in the ORB */958		ret = sbp_run_transaction(sess->card, TCODE_READ_BLOCK_REQUEST,959				sess->node_id, sess->generation, sess->speed,960				req->orb_pointer, &req->orb, sizeof(req->orb));961		if (ret != RCODE_COMPLETE) {962			pr_debug("tgt_orb fetch failed: %x\n", ret);963			req->status.status |= cpu_to_be32(964					STATUS_BLOCK_SRC(965						STATUS_SRC_ORB_FINISHED) |966					STATUS_BLOCK_RESP(967						STATUS_RESP_TRANSPORT_FAILURE) |968					STATUS_BLOCK_DEAD(1) |969					STATUS_BLOCK_LEN(1) |970					STATUS_BLOCK_SBP_STATUS(971						SBP_STATUS_UNSPECIFIED_ERROR));972			spin_lock_bh(&agent->lock);973			agent->state = AGENT_STATE_DEAD;974			spin_unlock_bh(&agent->lock);975 976			sbp_send_status(req);977			return;978		}979 980		/* check the next_ORB field */981		if (be32_to_cpu(req->orb.next_orb.high) & 0x80000000) {982			next_orb = 0;983			req->status.status |= cpu_to_be32(STATUS_BLOCK_SRC(984						STATUS_SRC_ORB_FINISHED));985		} else {986			next_orb = sbp2_pointer_to_addr(&req->orb.next_orb);987			req->status.status |= cpu_to_be32(STATUS_BLOCK_SRC(988						STATUS_SRC_ORB_CONTINUING));989		}990 991		if (tgt_agent_check_active(agent) && !doorbell) {992			INIT_WORK(&req->work, tgt_agent_process_work);993			queue_work(system_unbound_wq, &req->work);994		} else {995			/* don't process this request, just check next_ORB */996			sbp_free_request(req);997		}998 999		spin_lock_bh(&agent->lock);1000		doorbell = agent->doorbell = false;1001 1002		/* check if we should carry on processing */1003		if (next_orb)1004			agent->orb_pointer = next_orb;1005		else1006			agent->state = AGENT_STATE_SUSPENDED;1007 1008		spin_unlock_bh(&agent->lock);1009	}1010}1011 1012static struct sbp_target_agent *sbp_target_agent_register(1013		struct sbp_login_descriptor *login)1014{1015	struct sbp_target_agent *agent;1016	int ret;1017 1018	agent = kmalloc(sizeof(*agent), GFP_KERNEL);1019	if (!agent)1020		return ERR_PTR(-ENOMEM);1021 1022	spin_lock_init(&agent->lock);1023 1024	agent->handler.length = 0x20;1025	agent->handler.address_callback = tgt_agent_rw;1026	agent->handler.callback_data = agent;1027 1028	agent->login = login;1029	agent->state = AGENT_STATE_RESET;1030	INIT_WORK(&agent->work, tgt_agent_fetch_work);1031	agent->orb_pointer = 0;1032	agent->doorbell = false;1033 1034	ret = fw_core_add_address_handler(&agent->handler,1035			&sbp_register_region);1036	if (ret < 0) {1037		kfree(agent);1038		return ERR_PTR(ret);1039	}1040 1041	return agent;1042}1043 1044static void sbp_target_agent_unregister(struct sbp_target_agent *agent)1045{1046	fw_core_remove_address_handler(&agent->handler);1047	cancel_work_sync(&agent->work);1048	kfree(agent);1049}1050 1051/*1052 * Simple wrapper around fw_run_transaction that retries the transaction several1053 * times in case of failure, with an exponential backoff.1054 */1055static int sbp_run_transaction(struct fw_card *card, int tcode, int destination_id,1056		int generation, int speed, unsigned long long offset,1057		void *payload, size_t length)1058{1059	int attempt, ret, delay;1060 1061	for (attempt = 1; attempt <= 5; attempt++) {1062		ret = fw_run_transaction(card, tcode, destination_id,1063				generation, speed, offset, payload, length);1064 1065		switch (ret) {1066		case RCODE_COMPLETE:1067		case RCODE_TYPE_ERROR:1068		case RCODE_ADDRESS_ERROR:1069		case RCODE_GENERATION:1070			return ret;1071 1072		default:1073			delay = 5 * attempt * attempt;1074			usleep_range(delay, delay * 2);1075		}1076	}1077 1078	return ret;1079}1080 1081/*1082 * Wrapper around sbp_run_transaction that gets the card, destination,1083 * generation and speed out of the request's session.1084 */1085static int sbp_run_request_transaction(struct sbp_target_request *req,1086		int tcode, unsigned long long offset, void *payload,1087		size_t length)1088{1089	struct sbp_login_descriptor *login = req->login;1090	struct sbp_session *sess = login->sess;1091	struct fw_card *card;1092	int node_id, generation, speed, ret;1093 1094	spin_lock_bh(&sess->lock);1095	card = fw_card_get(sess->card);1096	node_id = sess->node_id;1097	generation = sess->generation;1098	speed = sess->speed;1099	spin_unlock_bh(&sess->lock);1100 1101	ret = sbp_run_transaction(card, tcode, node_id, generation, speed,1102			offset, payload, length);1103 1104	fw_card_put(card);1105 1106	return ret;1107}1108 1109static int sbp_fetch_command(struct sbp_target_request *req)1110{1111	int ret, cmd_len, copy_len;1112 1113	cmd_len = scsi_command_size(req->orb.command_block);1114 1115	req->cmd_buf = kmalloc(cmd_len, GFP_KERNEL);1116	if (!req->cmd_buf)1117		return -ENOMEM;1118 1119	memcpy(req->cmd_buf, req->orb.command_block,1120		min_t(int, cmd_len, sizeof(req->orb.command_block)));1121 1122	if (cmd_len > sizeof(req->orb.command_block)) {1123		pr_debug("sbp_fetch_command: filling in long command\n");1124		copy_len = cmd_len - sizeof(req->orb.command_block);1125 1126		ret = sbp_run_request_transaction(req,1127				TCODE_READ_BLOCK_REQUEST,1128				req->orb_pointer + sizeof(req->orb),1129				req->cmd_buf + sizeof(req->orb.command_block),1130				copy_len);1131		if (ret != RCODE_COMPLETE)1132			return -EIO;1133	}1134 1135	return 0;1136}1137 1138static int sbp_fetch_page_table(struct sbp_target_request *req)1139{1140	int pg_tbl_sz, ret;1141	struct sbp_page_table_entry *pg_tbl;1142 1143	if (!CMDBLK_ORB_PG_TBL_PRESENT(be32_to_cpu(req->orb.misc)))1144		return 0;1145 1146	pg_tbl_sz = CMDBLK_ORB_DATA_SIZE(be32_to_cpu(req->orb.misc)) *1147		sizeof(struct sbp_page_table_entry);1148 1149	pg_tbl = kmalloc(pg_tbl_sz, GFP_KERNEL);1150	if (!pg_tbl)1151		return -ENOMEM;1152 1153	ret = sbp_run_request_transaction(req, TCODE_READ_BLOCK_REQUEST,1154			sbp2_pointer_to_addr(&req->orb.data_descriptor),1155			pg_tbl, pg_tbl_sz);1156	if (ret != RCODE_COMPLETE) {1157		kfree(pg_tbl);1158		return -EIO;1159	}1160 1161	req->pg_tbl = pg_tbl;1162	return 0;1163}1164 1165static void sbp_calc_data_length_direction(struct sbp_target_request *req,1166	u32 *data_len, enum dma_data_direction *data_dir)1167{1168	int data_size, direction, idx;1169 1170	data_size = CMDBLK_ORB_DATA_SIZE(be32_to_cpu(req->orb.misc));1171	direction = CMDBLK_ORB_DIRECTION(be32_to_cpu(req->orb.misc));1172 1173	if (!data_size) {1174		*data_len = 0;1175		*data_dir = DMA_NONE;1176		return;1177	}1178 1179	*data_dir = direction ? DMA_FROM_DEVICE : DMA_TO_DEVICE;1180 1181	if (req->pg_tbl) {1182		*data_len = 0;1183		for (idx = 0; idx < data_size; idx++) {1184			*data_len += be16_to_cpu(1185					req->pg_tbl[idx].segment_length);1186		}1187	} else {1188		*data_len = data_size;1189	}1190}1191 1192static void sbp_handle_command(struct sbp_target_request *req)1193{1194	struct sbp_login_descriptor *login = req->login;1195	struct sbp_session *sess = login->sess;1196	int ret, unpacked_lun;1197	u32 data_length;1198	enum dma_data_direction data_dir;1199 1200	ret = sbp_fetch_command(req);1201	if (ret) {1202		pr_debug("sbp_handle_command: fetch command failed: %d\n", ret);1203		goto err;1204	}1205 1206	ret = sbp_fetch_page_table(req);1207	if (ret) {1208		pr_debug("sbp_handle_command: fetch page table failed: %d\n",1209			ret);1210		goto err;1211	}1212 1213	unpacked_lun = req->login->login_lun;1214	sbp_calc_data_length_direction(req, &data_length, &data_dir);1215 1216	pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n",1217			req->orb_pointer, unpacked_lun, data_length, data_dir);1218 1219	/* only used for printk until we do TMRs */1220	req->se_cmd.tag = req->orb_pointer;1221	target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf,1222			  req->sense_buf, unpacked_lun, data_length,1223			  TCM_SIMPLE_TAG, data_dir, TARGET_SCF_ACK_KREF);1224	return;1225 1226err:1227	req->status.status |= cpu_to_be32(1228		STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |1229		STATUS_BLOCK_DEAD(0) |1230		STATUS_BLOCK_LEN(1) |1231		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));1232	sbp_send_status(req);1233}1234 1235/*1236 * DMA_TO_DEVICE = read from initiator (SCSI WRITE)1237 * DMA_FROM_DEVICE = write to initiator (SCSI READ)1238 */1239static int sbp_rw_data(struct sbp_target_request *req)1240{1241	struct sbp_session *sess = req->login->sess;1242	int tcode, sg_miter_flags, max_payload, pg_size, speed, node_id,1243		generation, num_pte, length, tfr_length,1244		rcode = RCODE_COMPLETE;1245	struct sbp_page_table_entry *pte;1246	unsigned long long offset;1247	struct fw_card *card;1248	struct sg_mapping_iter iter;1249 1250	if (req->se_cmd.data_direction == DMA_FROM_DEVICE) {1251		tcode = TCODE_WRITE_BLOCK_REQUEST;1252		sg_miter_flags = SG_MITER_FROM_SG;1253	} else {1254		tcode = TCODE_READ_BLOCK_REQUEST;1255		sg_miter_flags = SG_MITER_TO_SG;1256	}1257 1258	max_payload = 4 << CMDBLK_ORB_MAX_PAYLOAD(be32_to_cpu(req->orb.misc));1259	speed = CMDBLK_ORB_SPEED(be32_to_cpu(req->orb.misc));1260 1261	pg_size = CMDBLK_ORB_PG_SIZE(be32_to_cpu(req->orb.misc));1262	if (pg_size) {1263		pr_err("sbp_run_transaction: page size ignored\n");1264	}1265 1266	spin_lock_bh(&sess->lock);1267	card = fw_card_get(sess->card);1268	node_id = sess->node_id;1269	generation = sess->generation;1270	spin_unlock_bh(&sess->lock);1271 1272	if (req->pg_tbl) {1273		pte = req->pg_tbl;1274		num_pte = CMDBLK_ORB_DATA_SIZE(be32_to_cpu(req->orb.misc));1275 1276		offset = 0;1277		length = 0;1278	} else {1279		pte = NULL;1280		num_pte = 0;1281 1282		offset = sbp2_pointer_to_addr(&req->orb.data_descriptor);1283		length = req->se_cmd.data_length;1284	}1285 1286	sg_miter_start(&iter, req->se_cmd.t_data_sg, req->se_cmd.t_data_nents,1287		sg_miter_flags);1288 1289	while (length || num_pte) {1290		if (!length) {1291			offset = (u64)be16_to_cpu(pte->segment_base_hi) << 32 |1292				be32_to_cpu(pte->segment_base_lo);1293			length = be16_to_cpu(pte->segment_length);1294 1295			pte++;1296			num_pte--;1297		}1298 1299		sg_miter_next(&iter);1300 1301		tfr_length = min3(length, max_payload, (int)iter.length);1302 1303		/* FIXME: take page_size into account */1304 1305		rcode = sbp_run_transaction(card, tcode, node_id,1306				generation, speed,1307				offset, iter.addr, tfr_length);1308 1309		if (rcode != RCODE_COMPLETE)1310			break;1311 1312		length -= tfr_length;1313		offset += tfr_length;1314		iter.consumed = tfr_length;1315	}1316 1317	sg_miter_stop(&iter);1318	fw_card_put(card);1319 1320	if (rcode == RCODE_COMPLETE) {1321		WARN_ON(length != 0);1322		return 0;1323	} else {1324		return -EIO;1325	}1326}1327 1328static int sbp_send_status(struct sbp_target_request *req)1329{1330	int rc, ret = 0, length;1331	struct sbp_login_descriptor *login = req->login;1332 1333	length = (((be32_to_cpu(req->status.status) >> 24) & 0x07) + 1) * 4;1334 1335	rc = sbp_run_request_transaction(req, TCODE_WRITE_BLOCK_REQUEST,1336			login->status_fifo_addr, &req->status, length);1337	if (rc != RCODE_COMPLETE) {1338		pr_debug("sbp_send_status: write failed: 0x%x\n", rc);1339		ret = -EIO;1340		goto put_ref;1341	}1342 1343	pr_debug("sbp_send_status: status write complete for ORB: 0x%llx\n",1344			req->orb_pointer);1345	/*1346	 * Drop the extra ACK_KREF reference taken by target_submit_cmd()1347	 * ahead of sbp_check_stop_free() -> transport_generic_free_cmd()1348	 * final se_cmd->cmd_kref put.1349	 */1350put_ref:1351	target_put_sess_cmd(&req->se_cmd);1352	return ret;1353}1354 1355static void sbp_sense_mangle(struct sbp_target_request *req)1356{1357	struct se_cmd *se_cmd = &req->se_cmd;1358	u8 *sense = req->sense_buf;1359	u8 *status = req->status.data;1360 1361	WARN_ON(se_cmd->scsi_sense_length < 18);1362 1363	switch (sense[0] & 0x7f) { 		/* sfmt */1364	case 0x70: /* current, fixed */1365		status[0] = 0 << 6;1366		break;1367	case 0x71: /* deferred, fixed */1368		status[0] = 1 << 6;1369		break;1370	case 0x72: /* current, descriptor */1371	case 0x73: /* deferred, descriptor */1372	default:1373		/*1374		 * TODO: SBP-3 specifies what we should do with descriptor1375		 * format sense data1376		 */1377		pr_err("sbp_send_sense: unknown sense format: 0x%x\n",1378			sense[0]);1379		req->status.status |= cpu_to_be32(1380			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1381			STATUS_BLOCK_DEAD(0) |1382			STATUS_BLOCK_LEN(1) |1383			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQUEST_ABORTED));1384		return;1385	}1386 1387	status[0] |= se_cmd->scsi_status & 0x3f;/* status */1388	status[1] =1389		(sense[0] & 0x80) |		/* valid */1390		((sense[2] & 0xe0) >> 1) |	/* mark, eom, ili */1391		(sense[2] & 0x0f);		/* sense_key */1392	status[2] = 0;				/* XXX sense_code */1393	status[3] = 0;				/* XXX sense_qualifier */1394 1395	/* information */1396	status[4] = sense[3];1397	status[5] = sense[4];1398	status[6] = sense[5];1399	status[7] = sense[6];1400 1401	/* CDB-dependent */1402	status[8] = sense[8];1403	status[9] = sense[9];1404	status[10] = sense[10];1405	status[11] = sense[11];1406 1407	/* fru */1408	status[12] = sense[14];1409 1410	/* sense_key-dependent */1411	status[13] = sense[15];1412	status[14] = sense[16];1413	status[15] = sense[17];1414 1415	req->status.status |= cpu_to_be32(1416		STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1417		STATUS_BLOCK_DEAD(0) |1418		STATUS_BLOCK_LEN(5) |1419		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_OK));1420}1421 1422static int sbp_send_sense(struct sbp_target_request *req)1423{1424	struct se_cmd *se_cmd = &req->se_cmd;1425 1426	if (se_cmd->scsi_sense_length) {1427		sbp_sense_mangle(req);1428	} else {1429		req->status.status |= cpu_to_be32(1430			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1431			STATUS_BLOCK_DEAD(0) |1432			STATUS_BLOCK_LEN(1) |1433			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_OK));1434	}1435 1436	return sbp_send_status(req);1437}1438 1439static void sbp_free_request(struct sbp_target_request *req)1440{1441	struct se_cmd *se_cmd = &req->se_cmd;1442	struct se_session *se_sess = se_cmd->se_sess;1443 1444	kfree(req->pg_tbl);1445	kfree(req->cmd_buf);1446 1447	target_free_tag(se_sess, se_cmd);1448}1449 1450static void sbp_mgt_agent_process(struct work_struct *work)1451{1452	struct sbp_management_agent *agent =1453		container_of(work, struct sbp_management_agent, work);1454	struct sbp_management_request *req = agent->request;1455	int ret;1456	int status_data_len = 0;1457 1458	/* fetch the ORB from the initiator */1459	ret = sbp_run_transaction(req->card, TCODE_READ_BLOCK_REQUEST,1460		req->node_addr, req->generation, req->speed,1461		agent->orb_offset, &req->orb, sizeof(req->orb));1462	if (ret != RCODE_COMPLETE) {1463		pr_debug("mgt_orb fetch failed: %x\n", ret);1464		goto out;1465	}1466 1467	pr_debug("mgt_orb ptr1:0x%llx ptr2:0x%llx misc:0x%x len:0x%x status_fifo:0x%llx\n",1468		sbp2_pointer_to_addr(&req->orb.ptr1),1469		sbp2_pointer_to_addr(&req->orb.ptr2),1470		be32_to_cpu(req->orb.misc), be32_to_cpu(req->orb.length),1471		sbp2_pointer_to_addr(&req->orb.status_fifo));1472 1473	if (!ORB_NOTIFY(be32_to_cpu(req->orb.misc)) ||1474		ORB_REQUEST_FORMAT(be32_to_cpu(req->orb.misc)) != 0) {1475		pr_err("mgt_orb bad request\n");1476		goto out;1477	}1478 1479	switch (MANAGEMENT_ORB_FUNCTION(be32_to_cpu(req->orb.misc))) {1480	case MANAGEMENT_ORB_FUNCTION_LOGIN:1481		sbp_management_request_login(agent, req, &status_data_len);1482		break;1483 1484	case MANAGEMENT_ORB_FUNCTION_QUERY_LOGINS:1485		sbp_management_request_query_logins(agent, req,1486				&status_data_len);1487		break;1488 1489	case MANAGEMENT_ORB_FUNCTION_RECONNECT:1490		sbp_management_request_reconnect(agent, req, &status_data_len);1491		break;1492 1493	case MANAGEMENT_ORB_FUNCTION_SET_PASSWORD:1494		pr_notice("SET PASSWORD not implemented\n");1495 1496		req->status.status = cpu_to_be32(1497			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1498			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1499 1500		break;1501 1502	case MANAGEMENT_ORB_FUNCTION_LOGOUT:1503		sbp_management_request_logout(agent, req, &status_data_len);1504		break;1505 1506	case MANAGEMENT_ORB_FUNCTION_ABORT_TASK:1507		pr_notice("ABORT TASK not implemented\n");1508 1509		req->status.status = cpu_to_be32(1510			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1511			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1512 1513		break;1514 1515	case MANAGEMENT_ORB_FUNCTION_ABORT_TASK_SET:1516		pr_notice("ABORT TASK SET not implemented\n");1517 1518		req->status.status = cpu_to_be32(1519			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1520			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1521 1522		break;1523 1524	case MANAGEMENT_ORB_FUNCTION_LOGICAL_UNIT_RESET:1525		pr_notice("LOGICAL UNIT RESET not implemented\n");1526 1527		req->status.status = cpu_to_be32(1528			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1529			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1530 1531		break;1532 1533	case MANAGEMENT_ORB_FUNCTION_TARGET_RESET:1534		pr_notice("TARGET RESET not implemented\n");1535 1536		req->status.status = cpu_to_be32(1537			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1538			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1539 1540		break;1541 1542	default:1543		pr_notice("unknown management function 0x%x\n",1544			MANAGEMENT_ORB_FUNCTION(be32_to_cpu(req->orb.misc)));1545 1546		req->status.status = cpu_to_be32(1547			STATUS_BLOCK_RESP(STATUS_RESP_REQUEST_COMPLETE) |1548			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_REQ_TYPE_NOTSUPP));1549 1550		break;1551	}1552 1553	req->status.status |= cpu_to_be32(1554		STATUS_BLOCK_SRC(1) | /* Response to ORB, next_ORB absent */1555		STATUS_BLOCK_LEN(DIV_ROUND_UP(status_data_len, 4) + 1) |1556		STATUS_BLOCK_ORB_OFFSET_HIGH(agent->orb_offset >> 32));1557	req->status.orb_low = cpu_to_be32(agent->orb_offset);1558 1559	/* write the status block back to the initiator */1560	ret = sbp_run_transaction(req->card, TCODE_WRITE_BLOCK_REQUEST,1561		req->node_addr, req->generation, req->speed,1562		sbp2_pointer_to_addr(&req->orb.status_fifo),1563		&req->status, 8 + status_data_len);1564	if (ret != RCODE_COMPLETE) {1565		pr_debug("mgt_orb status write failed: %x\n", ret);1566		goto out;1567	}1568 1569out:1570	fw_card_put(req->card);1571	kfree(req);1572 1573	spin_lock_bh(&agent->lock);1574	agent->state = MANAGEMENT_AGENT_STATE_IDLE;1575	spin_unlock_bh(&agent->lock);1576}1577 1578static void sbp_mgt_agent_rw(struct fw_card *card,1579	struct fw_request *request, int tcode, int destination, int source,1580	int generation, unsigned long long offset, void *data, size_t length,1581	void *callback_data)1582{1583	struct sbp_management_agent *agent = callback_data;1584	struct sbp2_pointer *ptr = data;1585	int rcode = RCODE_ADDRESS_ERROR;1586 1587	if (!agent->tport->enable)1588		goto out;1589 1590	if ((offset != agent->handler.offset) || (length != 8))1591		goto out;1592 1593	if (tcode == TCODE_WRITE_BLOCK_REQUEST) {1594		struct sbp_management_request *req;1595		int prev_state;1596 1597		spin_lock_bh(&agent->lock);1598		prev_state = agent->state;1599		agent->state = MANAGEMENT_AGENT_STATE_BUSY;1600		spin_unlock_bh(&agent->lock);1601 1602		if (prev_state == MANAGEMENT_AGENT_STATE_BUSY) {1603			pr_notice("ignoring management request while busy\n");1604			rcode = RCODE_CONFLICT_ERROR;1605			goto out;1606		}1607		req = kzalloc(sizeof(*req), GFP_ATOMIC);1608		if (!req) {1609			rcode = RCODE_CONFLICT_ERROR;1610			goto out;1611		}1612 1613		req->card = fw_card_get(card);1614		req->generation = generation;1615		req->node_addr = source;1616		req->speed = fw_get_request_speed(request);1617 1618		agent->orb_offset = sbp2_pointer_to_addr(ptr);1619		agent->request = req;1620 1621		queue_work(system_unbound_wq, &agent->work);1622		rcode = RCODE_COMPLETE;1623	} else if (tcode == TCODE_READ_BLOCK_REQUEST) {1624		addr_to_sbp2_pointer(agent->orb_offset, ptr);1625		rcode = RCODE_COMPLETE;1626	} else {1627		rcode = RCODE_TYPE_ERROR;1628	}1629 1630out:1631	fw_send_response(card, request, rcode);1632}1633 1634static struct sbp_management_agent *sbp_management_agent_register(1635		struct sbp_tport *tport)1636{1637	int ret;1638	struct sbp_management_agent *agent;1639 1640	agent = kmalloc(sizeof(*agent), GFP_KERNEL);1641	if (!agent)1642		return ERR_PTR(-ENOMEM);1643 1644	spin_lock_init(&agent->lock);1645	agent->tport = tport;1646	agent->handler.length = 0x08;1647	agent->handler.address_callback = sbp_mgt_agent_rw;1648	agent->handler.callback_data = agent;1649	agent->state = MANAGEMENT_AGENT_STATE_IDLE;1650	INIT_WORK(&agent->work, sbp_mgt_agent_process);1651	agent->orb_offset = 0;1652	agent->request = NULL;1653 1654	ret = fw_core_add_address_handler(&agent->handler,1655			&sbp_register_region);1656	if (ret < 0) {1657		kfree(agent);1658		return ERR_PTR(ret);1659	}1660 1661	return agent;1662}1663 1664static void sbp_management_agent_unregister(struct sbp_management_agent *agent)1665{1666	fw_core_remove_address_handler(&agent->handler);1667	cancel_work_sync(&agent->work);1668	kfree(agent);1669}1670 1671static int sbp_check_true(struct se_portal_group *se_tpg)1672{1673	return 1;1674}1675 1676static char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg)1677{1678	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);1679	struct sbp_tport *tport = tpg->tport;1680 1681	return &tport->tport_name[0];1682}1683 1684static u16 sbp_get_tag(struct se_portal_group *se_tpg)1685{1686	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);1687	return tpg->tport_tpgt;1688}1689 1690static void sbp_release_cmd(struct se_cmd *se_cmd)1691{1692	struct sbp_target_request *req = container_of(se_cmd,1693			struct sbp_target_request, se_cmd);1694 1695	sbp_free_request(req);1696}1697 1698static int sbp_write_pending(struct se_cmd *se_cmd)1699{1700	struct sbp_target_request *req = container_of(se_cmd,1701			struct sbp_target_request, se_cmd);1702	int ret;1703 1704	ret = sbp_rw_data(req);1705	if (ret) {1706		req->status.status |= cpu_to_be32(1707			STATUS_BLOCK_RESP(1708				STATUS_RESP_TRANSPORT_FAILURE) |1709			STATUS_BLOCK_DEAD(0) |1710			STATUS_BLOCK_LEN(1) |1711			STATUS_BLOCK_SBP_STATUS(1712				SBP_STATUS_UNSPECIFIED_ERROR));1713		sbp_send_status(req);1714		return ret;1715	}1716 1717	target_execute_cmd(se_cmd);1718	return 0;1719}1720 1721static int sbp_queue_data_in(struct se_cmd *se_cmd)1722{1723	struct sbp_target_request *req = container_of(se_cmd,1724			struct sbp_target_request, se_cmd);1725	int ret;1726 1727	ret = sbp_rw_data(req);1728	if (ret) {1729		req->status.status |= cpu_to_be32(1730			STATUS_BLOCK_RESP(STATUS_RESP_TRANSPORT_FAILURE) |1731			STATUS_BLOCK_DEAD(0) |1732			STATUS_BLOCK_LEN(1) |1733			STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));1734		sbp_send_status(req);1735		return ret;1736	}1737 1738	return sbp_send_sense(req);1739}1740 1741/*1742 * Called after command (no data transfer) or after the write (to device)1743 * operation is completed1744 */1745static int sbp_queue_status(struct se_cmd *se_cmd)1746{1747	struct sbp_target_request *req = container_of(se_cmd,1748			struct sbp_target_request, se_cmd);1749 1750	return sbp_send_sense(req);1751}1752 1753static void sbp_queue_tm_rsp(struct se_cmd *se_cmd)1754{1755}1756 1757static void sbp_aborted_task(struct se_cmd *se_cmd)1758{1759	return;1760}1761 1762static int sbp_check_stop_free(struct se_cmd *se_cmd)1763{1764	struct sbp_target_request *req = container_of(se_cmd,1765			struct sbp_target_request, se_cmd);1766 1767	return transport_generic_free_cmd(&req->se_cmd, 0);1768}1769 1770static int sbp_count_se_tpg_luns(struct se_portal_group *tpg)1771{1772	struct se_lun *lun;1773	int count = 0;1774 1775	rcu_read_lock();1776	hlist_for_each_entry_rcu(lun, &tpg->tpg_lun_hlist, link)1777		count++;1778	rcu_read_unlock();1779 1780	return count;1781}1782 1783static int sbp_update_unit_directory(struct sbp_tport *tport)1784{1785	struct se_lun *lun;1786	int num_luns, num_entries, idx = 0, mgt_agt_addr, ret;1787	u32 *data;1788 1789	if (tport->unit_directory.data) {1790		fw_core_remove_descriptor(&tport->unit_directory);1791		kfree(tport->unit_directory.data);1792		tport->unit_directory.data = NULL;1793	}1794 1795	if (!tport->enable || !tport->tpg)1796		return 0;1797 1798	num_luns = sbp_count_se_tpg_luns(&tport->tpg->se_tpg);1799 1800	/*1801	 * Number of entries in the final unit directory:1802	 *  - all of those in the template1803	 *  - management_agent1804	 *  - unit_characteristics1805	 *  - reconnect_timeout1806	 *  - unit unique ID1807	 *  - one for each LUN1808	 *1809	 *  MUST NOT include leaf or sub-directory entries1810	 */1811	num_entries = ARRAY_SIZE(sbp_unit_directory_template) + 4 + num_luns;1812 1813	if (tport->directory_id != -1)1814		num_entries++;1815 1816	/* allocate num_entries + 4 for the header and unique ID leaf */1817	data = kcalloc((num_entries + 4), sizeof(u32), GFP_KERNEL);1818	if (!data)1819		return -ENOMEM;1820 1821	/* directory_length */1822	data[idx++] = num_entries << 16;1823 1824	/* directory_id */1825	if (tport->directory_id != -1)1826		data[idx++] = (CSR_DIRECTORY_ID << 24) | tport->directory_id;1827 1828	/* unit directory template */1829	memcpy(&data[idx], sbp_unit_directory_template,1830			sizeof(sbp_unit_directory_template));1831	idx += ARRAY_SIZE(sbp_unit_directory_template);1832 1833	/* management_agent */1834	mgt_agt_addr = (tport->mgt_agt->handler.offset - CSR_REGISTER_BASE) / 4;1835	data[idx++] = 0x54000000 | (mgt_agt_addr & 0x00ffffff);1836 1837	/* unit_characteristics */1838	data[idx++] = 0x3a000000 |1839		(((tport->mgt_orb_timeout * 2) << 8) & 0xff00) |1840		SBP_ORB_FETCH_SIZE;1841 1842	/* reconnect_timeout */1843	data[idx++] = 0x3d000000 | (tport->max_reconnect_timeout & 0xffff);1844 1845	/* unit unique ID (leaf is just after LUNs) */1846	data[idx++] = 0x8d000000 | (num_luns + 1);1847 1848	rcu_read_lock();1849	hlist_for_each_entry_rcu(lun, &tport->tpg->se_tpg.tpg_lun_hlist, link) {1850		struct se_device *dev;1851		int type;1852		/*1853		 * rcu_dereference_raw protected by se_lun->lun_group symlink1854		 * reference to se_device->dev_group.1855		 */1856		dev = rcu_dereference_raw(lun->lun_se_dev);1857		type = dev->transport->get_device_type(dev);1858 1859		/* logical_unit_number */1860		data[idx++] = 0x14000000 |1861			((type << 16) & 0x1f0000) |1862			(lun->unpacked_lun & 0xffff);1863	}1864	rcu_read_unlock();1865 1866	/* unit unique ID leaf */1867	data[idx++] = 2 << 16;1868	data[idx++] = tport->guid >> 32;1869	data[idx++] = tport->guid;1870 1871	tport->unit_directory.length = idx;1872	tport->unit_directory.key = (CSR_DIRECTORY | CSR_UNIT) << 24;1873	tport->unit_directory.data = data;1874 1875	ret = fw_core_add_descriptor(&tport->unit_directory);1876	if (ret < 0) {1877		kfree(tport->unit_directory.data);1878		tport->unit_directory.data = NULL;1879	}1880 1881	return ret;1882}1883 1884static ssize_t sbp_parse_wwn(const char *name, u64 *wwn)1885{1886	const char *cp;1887	char c, nibble;1888	int pos = 0, err;1889 1890	*wwn = 0;1891	for (cp = name; cp < &name[SBP_NAMELEN - 1]; cp++) {1892		c = *cp;1893		if (c == '\n' && cp[1] == '\0')1894			continue;1895		if (c == '\0') {1896			err = 2;1897			if (pos != 16)1898				goto fail;1899			return cp - name;1900		}1901		err = 3;1902		if (isdigit(c))1903			nibble = c - '0';1904		else if (isxdigit(c))1905			nibble = tolower(c) - 'a' + 10;1906		else1907			goto fail;1908		*wwn = (*wwn << 4) | nibble;1909		pos++;1910	}1911	err = 4;1912fail:1913	printk(KERN_INFO "err %u len %zu pos %u\n",1914			err, cp - name, pos);1915	return -1;1916}1917 1918static ssize_t sbp_format_wwn(char *buf, size_t len, u64 wwn)1919{1920	return snprintf(buf, len, "%016llx", wwn);1921}1922 1923static int sbp_init_nodeacl(struct se_node_acl *se_nacl, const char *name)1924{1925	u64 guid = 0;1926 1927	if (sbp_parse_wwn(name, &guid) < 0)1928		return -EINVAL;1929	return 0;1930}1931 1932static int sbp_post_link_lun(1933		struct se_portal_group *se_tpg,1934		struct se_lun *se_lun)1935{1936	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);1937 1938	return sbp_update_unit_directory(tpg->tport);1939}1940 1941static void sbp_pre_unlink_lun(1942		struct se_portal_group *se_tpg,1943		struct se_lun *se_lun)1944{1945	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);1946	struct sbp_tport *tport = tpg->tport;1947	int ret;1948 1949	if (sbp_count_se_tpg_luns(&tpg->se_tpg) == 0)1950		tport->enable = 0;1951 1952	ret = sbp_update_unit_directory(tport);1953	if (ret < 0)1954		pr_err("unlink LUN: failed to update unit directory\n");1955}1956 1957static struct se_portal_group *sbp_make_tpg(struct se_wwn *wwn,1958					    const char *name)1959{1960	struct sbp_tport *tport =1961		container_of(wwn, struct sbp_tport, tport_wwn);1962 1963	struct sbp_tpg *tpg;1964	unsigned long tpgt;1965	int ret;1966 1967	if (strstr(name, "tpgt_") != name)1968		return ERR_PTR(-EINVAL);1969	if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)1970		return ERR_PTR(-EINVAL);1971 1972	if (tport->tpg) {1973		pr_err("Only one TPG per Unit is possible.\n");1974		return ERR_PTR(-EBUSY);1975	}1976 1977	tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);1978	if (!tpg)1979		return ERR_PTR(-ENOMEM);1980 1981	tpg->tport = tport;1982	tpg->tport_tpgt = tpgt;1983	tport->tpg = tpg;1984 1985	/* default attribute values */1986	tport->enable = 0;1987	tport->directory_id = -1;1988	tport->mgt_orb_timeout = 15;1989	tport->max_reconnect_timeout = 5;1990	tport->max_logins_per_lun = 1;1991 1992	tport->mgt_agt = sbp_management_agent_register(tport);1993	if (IS_ERR(tport->mgt_agt)) {1994		ret = PTR_ERR(tport->mgt_agt);1995		goto out_free_tpg;1996	}1997 1998	ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP);1999	if (ret < 0)2000		goto out_unreg_mgt_agt;2001 2002	return &tpg->se_tpg;2003 2004out_unreg_mgt_agt:2005	sbp_management_agent_unregister(tport->mgt_agt);2006out_free_tpg:2007	tport->tpg = NULL;2008	kfree(tpg);2009	return ERR_PTR(ret);2010}2011 2012static void sbp_drop_tpg(struct se_portal_group *se_tpg)2013{2014	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2015	struct sbp_tport *tport = tpg->tport;2016 2017	core_tpg_deregister(se_tpg);2018	sbp_management_agent_unregister(tport->mgt_agt);2019	tport->tpg = NULL;2020	kfree(tpg);2021}2022 2023static struct se_wwn *sbp_make_tport(2024		struct target_fabric_configfs *tf,2025		struct config_group *group,2026		const char *name)2027{2028	struct sbp_tport *tport;2029	u64 guid = 0;2030 2031	if (sbp_parse_wwn(name, &guid) < 0)2032		return ERR_PTR(-EINVAL);2033 2034	tport = kzalloc(sizeof(*tport), GFP_KERNEL);2035	if (!tport)2036		return ERR_PTR(-ENOMEM);2037 2038	tport->guid = guid;2039	sbp_format_wwn(tport->tport_name, SBP_NAMELEN, guid);2040 2041	return &tport->tport_wwn;2042}2043 2044static void sbp_drop_tport(struct se_wwn *wwn)2045{2046	struct sbp_tport *tport =2047		container_of(wwn, struct sbp_tport, tport_wwn);2048 2049	kfree(tport);2050}2051 2052static ssize_t sbp_wwn_version_show(struct config_item *item, char *page)2053{2054	return sprintf(page, "FireWire SBP fabric module %s\n", SBP_VERSION);2055}2056 2057CONFIGFS_ATTR_RO(sbp_wwn_, version);2058 2059static struct configfs_attribute *sbp_wwn_attrs[] = {2060	&sbp_wwn_attr_version,2061	NULL,2062};2063 2064static ssize_t sbp_tpg_directory_id_show(struct config_item *item, char *page)2065{2066	struct se_portal_group *se_tpg = to_tpg(item);2067	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2068	struct sbp_tport *tport = tpg->tport;2069 2070	if (tport->directory_id == -1)2071		return sprintf(page, "implicit\n");2072	else2073		return sprintf(page, "%06x\n", tport->directory_id);2074}2075 2076static ssize_t sbp_tpg_directory_id_store(struct config_item *item,2077		const char *page, size_t count)2078{2079	struct se_portal_group *se_tpg = to_tpg(item);2080	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2081	struct sbp_tport *tport = tpg->tport;2082	unsigned long val;2083 2084	if (tport->enable) {2085		pr_err("Cannot change the directory_id on an active target.\n");2086		return -EBUSY;2087	}2088 2089	if (strstr(page, "implicit") == page) {2090		tport->directory_id = -1;2091	} else {2092		if (kstrtoul(page, 16, &val) < 0)2093			return -EINVAL;2094		if (val > 0xffffff)2095			return -EINVAL;2096 2097		tport->directory_id = val;2098	}2099 2100	return count;2101}2102 2103static int sbp_enable_tpg(struct se_portal_group *se_tpg, bool enable)2104{2105	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2106	struct sbp_tport *tport = tpg->tport;2107	int ret;2108 2109	if (enable) {2110		if (sbp_count_se_tpg_luns(&tpg->se_tpg) == 0) {2111			pr_err("Cannot enable a target with no LUNs!\n");2112			return -EINVAL;2113		}2114	} else {2115		/* XXX: force-shutdown sessions instead? */2116		spin_lock_bh(&se_tpg->session_lock);2117		if (!list_empty(&se_tpg->tpg_sess_list)) {2118			spin_unlock_bh(&se_tpg->session_lock);2119			return -EBUSY;2120		}2121		spin_unlock_bh(&se_tpg->session_lock);2122	}2123 2124	tport->enable = enable;2125 2126	ret = sbp_update_unit_directory(tport);2127	if (ret < 0) {2128		pr_err("Could not update Config ROM\n");2129		return ret;2130	}2131 2132	return 0;2133}2134 2135CONFIGFS_ATTR(sbp_tpg_, directory_id);2136 2137static struct configfs_attribute *sbp_tpg_base_attrs[] = {2138	&sbp_tpg_attr_directory_id,2139	NULL,2140};2141 2142static ssize_t sbp_tpg_attrib_mgt_orb_timeout_show(struct config_item *item,2143		char *page)2144{2145	struct se_portal_group *se_tpg = attrib_to_tpg(item);2146	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2147	struct sbp_tport *tport = tpg->tport;2148	return sprintf(page, "%d\n", tport->mgt_orb_timeout);2149}2150 2151static ssize_t sbp_tpg_attrib_mgt_orb_timeout_store(struct config_item *item,2152		const char *page, size_t count)2153{2154	struct se_portal_group *se_tpg = attrib_to_tpg(item);2155	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2156	struct sbp_tport *tport = tpg->tport;2157	unsigned long val;2158	int ret;2159 2160	if (kstrtoul(page, 0, &val) < 0)2161		return -EINVAL;2162	if ((val < 1) || (val > 127))2163		return -EINVAL;2164 2165	if (tport->mgt_orb_timeout == val)2166		return count;2167 2168	tport->mgt_orb_timeout = val;2169 2170	ret = sbp_update_unit_directory(tport);2171	if (ret < 0)2172		return ret;2173 2174	return count;2175}2176 2177static ssize_t sbp_tpg_attrib_max_reconnect_timeout_show(struct config_item *item,2178		char *page)2179{2180	struct se_portal_group *se_tpg = attrib_to_tpg(item);2181	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2182	struct sbp_tport *tport = tpg->tport;2183	return sprintf(page, "%d\n", tport->max_reconnect_timeout);2184}2185 2186static ssize_t sbp_tpg_attrib_max_reconnect_timeout_store(struct config_item *item,2187		const char *page, size_t count)2188{2189	struct se_portal_group *se_tpg = attrib_to_tpg(item);2190	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2191	struct sbp_tport *tport = tpg->tport;2192	unsigned long val;2193	int ret;2194 2195	if (kstrtoul(page, 0, &val) < 0)2196		return -EINVAL;2197	if ((val < 1) || (val > 32767))2198		return -EINVAL;2199 2200	if (tport->max_reconnect_timeout == val)2201		return count;2202 2203	tport->max_reconnect_timeout = val;2204 2205	ret = sbp_update_unit_directory(tport);2206	if (ret < 0)2207		return ret;2208 2209	return count;2210}2211 2212static ssize_t sbp_tpg_attrib_max_logins_per_lun_show(struct config_item *item,2213		char *page)2214{2215	struct se_portal_group *se_tpg = attrib_to_tpg(item);2216	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2217	struct sbp_tport *tport = tpg->tport;2218	return sprintf(page, "%d\n", tport->max_logins_per_lun);2219}2220 2221static ssize_t sbp_tpg_attrib_max_logins_per_lun_store(struct config_item *item,2222		const char *page, size_t count)2223{2224	struct se_portal_group *se_tpg = attrib_to_tpg(item);2225	struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);2226	struct sbp_tport *tport = tpg->tport;2227	unsigned long val;2228 2229	if (kstrtoul(page, 0, &val) < 0)2230		return -EINVAL;2231	if ((val < 1) || (val > 127))2232		return -EINVAL;2233 2234	/* XXX: also check against current count? */2235 2236	tport->max_logins_per_lun = val;2237 2238	return count;2239}2240 2241CONFIGFS_ATTR(sbp_tpg_attrib_, mgt_orb_timeout);2242CONFIGFS_ATTR(sbp_tpg_attrib_, max_reconnect_timeout);2243CONFIGFS_ATTR(sbp_tpg_attrib_, max_logins_per_lun);2244 2245static struct configfs_attribute *sbp_tpg_attrib_attrs[] = {2246	&sbp_tpg_attrib_attr_mgt_orb_timeout,2247	&sbp_tpg_attrib_attr_max_reconnect_timeout,2248	&sbp_tpg_attrib_attr_max_logins_per_lun,2249	NULL,2250};2251 2252static const struct target_core_fabric_ops sbp_ops = {2253	.module				= THIS_MODULE,2254	.fabric_name			= "sbp",2255	.tpg_get_wwn			= sbp_get_fabric_wwn,2256	.tpg_get_tag			= sbp_get_tag,2257	.tpg_check_demo_mode		= sbp_check_true,2258	.tpg_check_demo_mode_cache	= sbp_check_true,2259	.release_cmd			= sbp_release_cmd,2260	.write_pending			= sbp_write_pending,2261	.queue_data_in			= sbp_queue_data_in,2262	.queue_status			= sbp_queue_status,2263	.queue_tm_rsp			= sbp_queue_tm_rsp,2264	.aborted_task			= sbp_aborted_task,2265	.check_stop_free		= sbp_check_stop_free,2266 2267	.fabric_make_wwn		= sbp_make_tport,2268	.fabric_drop_wwn		= sbp_drop_tport,2269	.fabric_make_tpg		= sbp_make_tpg,2270	.fabric_enable_tpg		= sbp_enable_tpg,2271	.fabric_drop_tpg		= sbp_drop_tpg,2272	.fabric_post_link		= sbp_post_link_lun,2273	.fabric_pre_unlink		= sbp_pre_unlink_lun,2274	.fabric_make_np			= NULL,2275	.fabric_drop_np			= NULL,2276	.fabric_init_nodeacl		= sbp_init_nodeacl,2277 2278	.tfc_wwn_attrs			= sbp_wwn_attrs,2279	.tfc_tpg_base_attrs		= sbp_tpg_base_attrs,2280	.tfc_tpg_attrib_attrs		= sbp_tpg_attrib_attrs,2281 2282	.default_submit_type		= TARGET_DIRECT_SUBMIT,2283	.direct_submit_supp		= 1,2284};2285 2286static int __init sbp_init(void)2287{2288	return target_register_template(&sbp_ops);2289};2290 2291static void __exit sbp_exit(void)2292{2293	target_unregister_template(&sbp_ops);2294};2295 2296MODULE_DESCRIPTION("FireWire SBP fabric driver");2297MODULE_LICENSE("GPL");2298module_init(sbp_init);2299module_exit(sbp_exit);2300