aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2008-06-10 12:20:55 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:25 -0400
commit45633fdc9615f9fd2a0ae18e301562298b15abf3 (patch)
tree8a91c7fffaf55d484c333443735572b4fb0c0a48 /drivers/s390/scsi/zfcp_fsf.c
parent24073b475d6d2bad8880434a16343ee1da816ea5 (diff)
[SCSI] zfcp: Move CFDC code to new file.
zfcp implements a device file to allow Linux guests changing the Access Control Tables stored in the adapter. The code for the device file has nothing to do with the other parts of the driver, so move it to a new file and cleanup the code while doing so. Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c246
1 files changed, 24 insertions, 222 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 8568b6f3f27c..de42a01fc4b1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -36,7 +36,7 @@ static int zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *);
36static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *); 36static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *);
37static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *); 37static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *);
38static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *); 38static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *);
39static int zfcp_fsf_control_file_handler(struct zfcp_fsf_req *); 39static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *);
40static inline int zfcp_fsf_req_sbal_check( 40static inline int zfcp_fsf_req_sbal_check(
41 unsigned long *, struct zfcp_qdio_queue *, int); 41 unsigned long *, struct zfcp_qdio_queue *, int);
42static inline int zfcp_use_one_sbal( 42static inline int zfcp_use_one_sbal(
@@ -4183,53 +4183,35 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
4183 * -ENOMEM - Insufficient memory 4183 * -ENOMEM - Insufficient memory
4184 * -EPERM - Cannot create FSF request or place it in QDIO queue 4184 * -EPERM - Cannot create FSF request or place it in QDIO queue
4185 */ 4185 */
4186int 4186struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
4187zfcp_fsf_control_file(struct zfcp_adapter *adapter, 4187 struct zfcp_fsf_cfdc *fsf_cfdc)
4188 struct zfcp_fsf_req **fsf_req_ptr,
4189 u32 fsf_command,
4190 u32 option,
4191 struct zfcp_sg_list *sg_list)
4192{ 4188{
4193 struct zfcp_fsf_req *fsf_req; 4189 struct zfcp_fsf_req *fsf_req;
4194 struct fsf_qtcb_bottom_support *bottom; 4190 struct fsf_qtcb_bottom_support *bottom;
4195 volatile struct qdio_buffer_element *sbale; 4191 volatile struct qdio_buffer_element *sbale;
4196 unsigned long lock_flags; 4192 unsigned long lock_flags;
4197 int req_flags = 0;
4198 int direction; 4193 int direction;
4199 int retval = 0; 4194 int retval;
4200 4195 int bytes;
4201 if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) {
4202 ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n",
4203 zfcp_get_busid_by_adapter(adapter));
4204 retval = -EOPNOTSUPP;
4205 goto out;
4206 }
4207 4196
4208 switch (fsf_command) { 4197 if (!(adapter->adapter_features & FSF_FEATURE_CFDC))
4198 return ERR_PTR(-EOPNOTSUPP);
4209 4199
4200 switch (fsf_cfdc->command) {
4210 case FSF_QTCB_DOWNLOAD_CONTROL_FILE: 4201 case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
4211 direction = SBAL_FLAGS0_TYPE_WRITE; 4202 direction = SBAL_FLAGS0_TYPE_WRITE;
4212 if ((option != FSF_CFDC_OPTION_FULL_ACCESS) &&
4213 (option != FSF_CFDC_OPTION_RESTRICTED_ACCESS))
4214 req_flags = ZFCP_WAIT_FOR_SBAL;
4215 break; 4203 break;
4216
4217 case FSF_QTCB_UPLOAD_CONTROL_FILE: 4204 case FSF_QTCB_UPLOAD_CONTROL_FILE:
4218 direction = SBAL_FLAGS0_TYPE_READ; 4205 direction = SBAL_FLAGS0_TYPE_READ;
4219 break; 4206 break;
4220
4221 default: 4207 default:
4222 ZFCP_LOG_INFO("Invalid FSF command code 0x%08x\n", fsf_command); 4208 return ERR_PTR(-EINVAL);
4223 retval = -EINVAL;
4224 goto out;
4225 } 4209 }
4226 4210
4227 retval = zfcp_fsf_req_create(adapter, fsf_command, req_flags, 4211 retval = zfcp_fsf_req_create(adapter, fsf_cfdc->command,
4212 ZFCP_WAIT_FOR_SBAL,
4228 NULL, &lock_flags, &fsf_req); 4213 NULL, &lock_flags, &fsf_req);
4229 if (retval < 0) { 4214 if (retval < 0) {
4230 ZFCP_LOG_INFO("error: Could not create FSF request for the "
4231 "adapter %s\n",
4232 zfcp_get_busid_by_adapter(adapter));
4233 retval = -EPERM; 4215 retval = -EPERM;
4234 goto unlock_queue_lock; 4216 goto unlock_queue_lock;
4235 } 4217 }
@@ -4239,220 +4221,40 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
4239 4221
4240 bottom = &fsf_req->qtcb->bottom.support; 4222 bottom = &fsf_req->qtcb->bottom.support;
4241 bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; 4223 bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
4242 bottom->option = option; 4224 bottom->option = fsf_cfdc->option;
4243 4225
4244 if (sg_list->count > 0) { 4226 bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction,
4245 int bytes; 4227 fsf_cfdc->sg, ZFCP_CFDC_PAGES,
4246 4228 ZFCP_MAX_SBALS_PER_REQ);
4247 bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction, 4229 if (bytes != ZFCP_CFDC_MAX_SIZE) {
4248 sg_list->sg, sg_list->count, 4230 retval = -ENOMEM;
4249 ZFCP_MAX_SBALS_PER_REQ); 4231 goto free_fsf_req;
4250 if (bytes != ZFCP_CFDC_MAX_CONTROL_FILE_SIZE) { 4232 }
4251 ZFCP_LOG_INFO(
4252 "error: Could not create sufficient number of "
4253 "SBALS for an FSF request to the adapter %s\n",
4254 zfcp_get_busid_by_adapter(adapter));
4255 retval = -ENOMEM;
4256 goto free_fsf_req;
4257 }
4258 } else
4259 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
4260 4233
4261 zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); 4234 zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
4262 retval = zfcp_fsf_req_send(fsf_req); 4235 retval = zfcp_fsf_req_send(fsf_req);
4263 if (retval < 0) { 4236 if (retval < 0) {
4264 ZFCP_LOG_INFO("initiation of cfdc up/download failed"
4265 "(adapter %s)\n",
4266 zfcp_get_busid_by_adapter(adapter));
4267 retval = -EPERM; 4237 retval = -EPERM;
4268 goto free_fsf_req; 4238 goto free_fsf_req;
4269 } 4239 }
4270 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); 4240 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
4271 4241
4272 ZFCP_LOG_NORMAL("Control file %s FSF request has been sent to the "
4273 "adapter %s\n",
4274 fsf_command == FSF_QTCB_DOWNLOAD_CONTROL_FILE ?
4275 "download" : "upload",
4276 zfcp_get_busid_by_adapter(adapter));
4277
4278 wait_event(fsf_req->completion_wq, 4242 wait_event(fsf_req->completion_wq,
4279 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); 4243 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
4280 4244
4281 *fsf_req_ptr = fsf_req; 4245 return fsf_req;
4282 goto out;
4283 4246
4284 free_fsf_req: 4247 free_fsf_req:
4285 zfcp_fsf_req_free(fsf_req); 4248 zfcp_fsf_req_free(fsf_req);
4286 unlock_queue_lock: 4249 unlock_queue_lock:
4287 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); 4250 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
4288 out: 4251 return ERR_PTR(retval);
4289 return retval;
4290} 4252}
4291 4253
4292 4254static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
4293/*
4294 * function: zfcp_fsf_control_file_handler
4295 *
4296 * purpose: Handler of the control file upload/download FSF requests
4297 *
4298 * returns: 0 - FSF request successfuly processed
4299 * -EAGAIN - Operation has to be repeated because of a temporary problem
4300 * -EACCES - There is no permission to execute an operation
4301 * -EPERM - The control file is not in a right format
4302 * -EIO - There is a problem with the FCP adapter
4303 * -EINVAL - Invalid operation
4304 * -EFAULT - User space memory I/O operation fault
4305 */
4306static int
4307zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
4308{ 4255{
4309 struct zfcp_adapter *adapter = fsf_req->adapter; 4256 if (fsf_req->qtcb->header.fsf_status != FSF_GOOD)
4310 struct fsf_qtcb_header *header = &fsf_req->qtcb->header;
4311 struct fsf_qtcb_bottom_support *bottom = &fsf_req->qtcb->bottom.support;
4312 int retval = 0;
4313
4314 if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
4315 retval = -EINVAL;
4316 goto skip_fsfstatus;
4317 }
4318
4319 switch (header->fsf_status) {
4320
4321 case FSF_GOOD:
4322 ZFCP_LOG_NORMAL(
4323 "The FSF request has been successfully completed "
4324 "on the adapter %s\n",
4325 zfcp_get_busid_by_adapter(adapter));
4326 break;
4327
4328 case FSF_OPERATION_PARTIALLY_SUCCESSFUL:
4329 if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) {
4330 switch (header->fsf_status_qual.word[0]) {
4331
4332 case FSF_SQ_CFDC_HARDENED_ON_SE:
4333 ZFCP_LOG_NORMAL(
4334 "CFDC on the adapter %s has being "
4335 "hardened on primary and secondary SE\n",
4336 zfcp_get_busid_by_adapter(adapter));
4337 break;
4338
4339 case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE:
4340 ZFCP_LOG_NORMAL(
4341 "CFDC of the adapter %s could not "
4342 "be saved on the SE\n",
4343 zfcp_get_busid_by_adapter(adapter));
4344 break;
4345
4346 case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2:
4347 ZFCP_LOG_NORMAL(
4348 "CFDC of the adapter %s could not "
4349 "be copied to the secondary SE\n",
4350 zfcp_get_busid_by_adapter(adapter));
4351 break;
4352
4353 default:
4354 ZFCP_LOG_NORMAL(
4355 "CFDC could not be hardened "
4356 "on the adapter %s\n",
4357 zfcp_get_busid_by_adapter(adapter));
4358 }
4359 }
4360 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4361 retval = -EAGAIN;
4362 break;
4363
4364 case FSF_AUTHORIZATION_FAILURE:
4365 ZFCP_LOG_NORMAL(
4366 "Adapter %s does not accept privileged commands\n",
4367 zfcp_get_busid_by_adapter(adapter));
4368 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4369 retval = -EACCES;
4370 break;
4371
4372 case FSF_CFDC_ERROR_DETECTED:
4373 ZFCP_LOG_NORMAL(
4374 "Error at position %d in the CFDC, "
4375 "CFDC is discarded by the adapter %s\n",
4376 header->fsf_status_qual.word[0],
4377 zfcp_get_busid_by_adapter(adapter));
4378 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4379 retval = -EPERM;
4380 break;
4381
4382 case FSF_CONTROL_FILE_UPDATE_ERROR:
4383 ZFCP_LOG_NORMAL(
4384 "Adapter %s cannot harden the control file, "
4385 "file is discarded\n",
4386 zfcp_get_busid_by_adapter(adapter));
4387 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4388 retval = -EIO;
4389 break;
4390
4391 case FSF_CONTROL_FILE_TOO_LARGE:
4392 ZFCP_LOG_NORMAL(
4393 "Control file is too large, file is discarded "
4394 "by the adapter %s\n",
4395 zfcp_get_busid_by_adapter(adapter));
4396 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4397 retval = -EIO;
4398 break;
4399
4400 case FSF_ACCESS_CONFLICT_DETECTED:
4401 if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
4402 ZFCP_LOG_NORMAL(
4403 "CFDC has been discarded by the adapter %s, "
4404 "because activation would impact "
4405 "%d active connection(s)\n",
4406 zfcp_get_busid_by_adapter(adapter),
4407 header->fsf_status_qual.word[0]);
4408 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4409 retval = -EIO;
4410 break;
4411
4412 case FSF_CONFLICTS_OVERRULED:
4413 if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
4414 ZFCP_LOG_NORMAL(
4415 "CFDC has been activated on the adapter %s, "
4416 "but activation has impacted "
4417 "%d active connection(s)\n",
4418 zfcp_get_busid_by_adapter(adapter),
4419 header->fsf_status_qual.word[0]);
4420 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4421 retval = -EIO;
4422 break;
4423
4424 case FSF_UNKNOWN_OP_SUBTYPE:
4425 ZFCP_LOG_NORMAL("unknown operation subtype (adapter: %s, "
4426 "op_subtype=0x%x)\n",
4427 zfcp_get_busid_by_adapter(adapter),
4428 bottom->operation_subtype);
4429 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4430 retval = -EINVAL;
4431 break;
4432
4433 case FSF_INVALID_COMMAND_OPTION:
4434 ZFCP_LOG_NORMAL(
4435 "Invalid option 0x%x has been specified "
4436 "in QTCB bottom sent to the adapter %s\n",
4437 bottom->option,
4438 zfcp_get_busid_by_adapter(adapter));
4439 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; 4257 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4440 retval = -EINVAL;
4441 break;
4442
4443 default:
4444 ZFCP_LOG_NORMAL(
4445 "bug: An unknown/unexpected FSF status 0x%08x "
4446 "was presented on the adapter %s\n",
4447 header->fsf_status,
4448 zfcp_get_busid_by_adapter(adapter));
4449 fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
4450 retval = -EINVAL;
4451 break;
4452 }
4453
4454skip_fsfstatus:
4455 return retval;
4456} 4258}
4457 4259
4458static inline int 4260static inline int