1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris * 52230557Sjimharris * $FreeBSD$ 53230557Sjimharris */ 54230557Sjimharris#ifndef _SATI_CALLBACKS_H_ 55230557Sjimharris#define _SATI_CALLBACKS_H_ 56230557Sjimharris 57230557Sjimharris/** 58230557Sjimharris * @file 59230557Sjimharris * @brief This file contains the default callback bindings for SATI. These 60230557Sjimharris * must be overridden by the SATI user to ensure successful operation. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/sati_types.h> 64230557Sjimharris#include <dev/isci/scil/intel_sas.h> 65230557Sjimharris 66230557Sjimharris#ifdef SATI_DEFAULT_DECLARATION 67230557Sjimharris 68230557Sjimharris/** 69230557Sjimharris * @brief This callback method asks the user to provide the address for 70230557Sjimharris * the command descriptor block (CDB) associated with this IO request. 71230557Sjimharris * 72230557Sjimharris * @param[in] scsi_io This parameter points to the user's IO request object 73230557Sjimharris * It is a cookie that allows the user to provide the necessary 74230557Sjimharris * information for this callback. 75230557Sjimharris * 76230557Sjimharris * @return This method returns the virtual address of the CDB. 77230557Sjimharris */ 78230557Sjimharrisvoid * sati_cb_get_cdb_address( 79230557Sjimharris void * scsi_io 80230557Sjimharris); 81230557Sjimharris 82230557Sjimharris/** 83230557Sjimharris * @brief This callback method asks the user to provide the length of 84230557Sjimharris * the command descriptor block (CDB) associated with this IO request. 85230557Sjimharris * 86230557Sjimharris * @param[in] scsi_io This parameter points to the user's IO request object. 87230557Sjimharris * It is a cookie that allows the user to provide the necessary 88230557Sjimharris * information for this callback. 89230557Sjimharris * 90230557Sjimharris * @return This method returns the length of the CDB. 91230557Sjimharris */ 92230557SjimharrisU32 sati_cb_get_cdb_length( 93230557Sjimharris void * scsi_io 94230557Sjimharris); 95230557Sjimharris 96230557Sjimharris/** 97230557Sjimharris * @brief This callback method asks the user to provide the data transfer 98230557Sjimharris * direction of this IO request. 99230557Sjimharris * 100230557Sjimharris * @param[in] scsi_io This parameter points to the user's IO request object. 101230557Sjimharris * It is a cookie that allows the user to provide the necessary 102230557Sjimharris * information for this callback. 103230557Sjimharris * @param[in] io_direction to return 104230557Sjimharris * @return This method returns the length of the CDB. 105230557Sjimharris */ 106230557Sjimharrisvoid sati_cb_get_data_direction( 107230557Sjimharris void * scsi_io, 108230557Sjimharris U8 * io_direction 109230557Sjimharris); 110230557Sjimharris 111230557Sjimharris/** 112230557Sjimharris * @brief This callback method sets a value into the data buffer associated 113230557Sjimharris * with the supplied user SCSI IO request at the supplied byte offset. 114230557Sjimharris * 115230557Sjimharris * @note SATI does not manage the user scatter-gather-list. As a result, 116230557Sjimharris * the user must ensure that data is written according to the SGL. 117230557Sjimharris * 118230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 119230557Sjimharris * for which to set the data buffer byte. 120230557Sjimharris * @param[in] byte_offset This parameter specifies the offset into the 121230557Sjimharris * data buffer at which to set the value. 122230557Sjimharris * @param[in] value This parameter specifies the new value to be set into 123230557Sjimharris * the data buffer. 124230557Sjimharris * 125230557Sjimharris * @return none 126230557Sjimharris */ 127230557Sjimharrisvoid sati_cb_set_data_byte( 128230557Sjimharris void * scsi_io, 129230557Sjimharris U32 byte_offset, 130230557Sjimharris U8 value 131230557Sjimharris); 132230557Sjimharris 133230557Sjimharris/** 134230557Sjimharris * @brief This callback method gets a value from the data buffer associated 135230557Sjimharris * with the supplied user SCSI IO request at the supplied byte offset. 136230557Sjimharris * 137230557Sjimharris * @note SATI does not manage the user scatter-gather-list. As a result, 138230557Sjimharris * the user must ensure that data is written according to the SGL. 139230557Sjimharris * 140230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 141230557Sjimharris * for which to get the data buffer byte. 142230557Sjimharris * @param[in] byte_offset This parameter specifies the offset into the 143230557Sjimharris * data buffer at which to get the value. 144230557Sjimharris * @param[in] value This parameter specifies the new value to be get into 145230557Sjimharris * the data buffer. 146230557Sjimharris * 147230557Sjimharris * @return none 148230557Sjimharris */ 149230557Sjimharrisvoid sati_cb_get_data_byte( 150230557Sjimharris void * scsi_io, 151230557Sjimharris U32 byte_offset, 152230557Sjimharris U8 * value 153230557Sjimharris); 154230557Sjimharris 155230557Sjimharris/** 156240518Seadler * @brief This callback method gets the task type for the SCSI task 157230557Sjimharris * request. 158230557Sjimharris * 159230557Sjimharris * @param[in] scsi_task This parameter specifies the user's SCSI Task request. 160230557Sjimharris * It is a cookie that allows the user to provide the necessary 161230557Sjimharris * information for this callback. 162230557Sjimharris * 163230557Sjimharris * @return This method returns one of the enumeration values for 164230557Sjimharris * SCSI_TASK_MGMT_REQUEST_CODES 165230557Sjimharris */ 166230557SjimharrisU8 sati_cb_get_task_function( 167230557Sjimharris void * scsi_task 168230557Sjimharris); 169230557Sjimharris 170230557Sjimharris#ifdef SATI_TRANSPORT_SUPPORTS_SAS 171230557Sjimharris/** 172230557Sjimharris * @brief This callback method retrieves the address of the user's SSP 173230557Sjimharris * response IU buffer. 174230557Sjimharris * 175230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 176230557Sjimharris * for which to retreive the location of the response buffer to 177230557Sjimharris * be written. 178230557Sjimharris * 179230557Sjimharris * @return This method returns the address of the response data buffer. 180230557Sjimharris */ 181230557Sjimharrisvoid * sati_cb_get_response_iu_address( 182230557Sjimharris void * scsi_io 183230557Sjimharris); 184230557Sjimharris 185230557Sjimharris#else // SATI_TRANSPORT_SUPPORTS_SAS 186230557Sjimharris 187230557Sjimharris/** 188230557Sjimharris * @brief This callback method retrieves the address of the user's sense data 189230557Sjimharris * buffer. 190230557Sjimharris * 191230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 192230557Sjimharris * for which to retreive the location of the sense buffer to 193230557Sjimharris * be written. 194230557Sjimharris * 195230557Sjimharris * @return This method returns the address of the sense data buffer. 196230557Sjimharris */ 197230557SjimharrisU8* sati_cb_get_sense_data_address( 198230557Sjimharris void * scsi_io 199230557Sjimharris); 200230557Sjimharris 201230557Sjimharris/** 202230557Sjimharris * @brief This callback method retrieves the length of the user's sense data 203230557Sjimharris * buffer. 204230557Sjimharris * 205230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 206230557Sjimharris * for which to retreive the location of the sense buffer to 207230557Sjimharris * be written. 208230557Sjimharris * 209230557Sjimharris * @return This method returns the length of the sense data buffer. 210230557Sjimharris */ 211230557SjimharrisU32 sati_cb_get_sense_data_length( 212230557Sjimharris void * scsi_io 213230557Sjimharris); 214230557Sjimharris 215230557Sjimharris/** 216230557Sjimharris * @brief This callback method sets the SCSI status to be associated with 217230557Sjimharris * the supplied user's SCSI IO request. 218230557Sjimharris * 219230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 220230557Sjimharris * for which to set the SCSI status. 221230557Sjimharris * @param[in] status This parameter specifies the SCSI status to be 222230557Sjimharris * associated with the supplied user's SCSI IO request. 223230557Sjimharris * 224230557Sjimharris * @return none 225230557Sjimharris */ 226230557Sjimharrisvoid sati_cb_set_scsi_status( 227230557Sjimharris void * scsi_io, 228230557Sjimharris U8 status 229230557Sjimharris); 230230557Sjimharris 231230557Sjimharris#endif // SATI_TRANSPORT_SUPPORTS_SAS 232230557Sjimharris 233230557Sjimharris/** 234230557Sjimharris * @brief This method retrieves the ATA task file (register FIS) relating to 235230557Sjimharris * the host to device command values. 236230557Sjimharris * 237230557Sjimharris * @param[in] ata_io This parameter specifies the user's ATA IO request 238230557Sjimharris * from which to retrieve the h2d register FIS address. 239230557Sjimharris * 240230557Sjimharris * @return This method returns the address for the host to device register 241230557Sjimharris * FIS. 242230557Sjimharris */ 243230557SjimharrisU8 * sati_cb_get_h2d_register_fis_address( 244230557Sjimharris void * ata_io 245230557Sjimharris); 246230557Sjimharris 247230557Sjimharris/** 248230557Sjimharris * @brief This method retrieves the ATA task file (register FIS) relating to 249230557Sjimharris * the device to host reponse values. 250230557Sjimharris * 251230557Sjimharris * @param[in] ata_io This parameter specifies the user's ATA IO request 252230557Sjimharris * from which to retrieve the d2h register FIS address. 253230557Sjimharris * 254230557Sjimharris * @return This method returns the address for the device to host register 255230557Sjimharris * FIS. 256230557Sjimharris */ 257230557SjimharrisU8 * sati_cb_get_d2h_register_fis_address( 258230557Sjimharris void * ata_io 259230557Sjimharris); 260230557Sjimharris 261230557Sjimharris/** 262230557Sjimharris * @brief This method retrieves the address where the ATA data received 263230557Sjimharris * from the device is stored. 264230557Sjimharris * 265230557Sjimharris * @param[in] ata_io This parameter specifies the user's ATA IO request 266230557Sjimharris * from which to retrieve the received data address. 267230557Sjimharris * 268230557Sjimharris * @return This method returns the address for the data received from 269230557Sjimharris * the remote device. 270230557Sjimharris */ 271230557Sjimharrisvoid * sati_cb_get_ata_data_address( 272230557Sjimharris void * ata_io 273230557Sjimharris); 274230557Sjimharris 275230557Sjimharris/** 276230557Sjimharris * @brief This method allocates a DMA buffer 277230557Sjimharris * that can be utilized for small (<=4K) DMA sequences. 278230557Sjimharris * This is utilized to translate SCSI UNMAP requests. 279230557Sjimharris * 280230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 281230557Sjimharris * for which to set the SCSI status. 282230557Sjimharris * @param[in] length in bytes of the buffer to be allocated 283230557Sjimharris * @param[in] virtual address of the allocated DMA buffer. 284230557Sjimharris * @param[in] low 32 bits of the physical DMA address. 285230557Sjimharris * @param[in] high 32 bits of the physical DMA address. 286230557Sjimharris * 287230557Sjimharris * @return This method returns the virtual and physical address 288230557Sjimharris * of the allocated DMA buffer. 289230557Sjimharris */ 290230557Sjimharrisvoid sati_cb_allocate_dma_buffer( 291230557Sjimharris void * scsi_io, 292230557Sjimharris U32 length, 293230557Sjimharris void ** virt_address, 294230557Sjimharris U32 * phys_address_low, 295230557Sjimharris U32 * phys_address_high 296230557Sjimharris); 297230557Sjimharris 298230557Sjimharris/** 299230557Sjimharris * @brief This method frees a previously allocated DMA buffer 300230557Sjimharris * 301230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 302230557Sjimharris * for which to set the SCSI status. 303230557Sjimharris * @param[in] address - write buffer address being freed 304230557Sjimharris * 305230557Sjimharris * @return This method returns the address for the data received from 306230557Sjimharris * the remote device. 307230557Sjimharris */ 308230557Sjimharrisvoid sati_cb_free_dma_buffer( 309230557Sjimharris void * scsi_io, 310230557Sjimharris void * virt_address 311230557Sjimharris); 312230557Sjimharris 313230557Sjimharris/** 314230557Sjimharris * @brief This method retrieves a pointer to the next scatter gather 315230557Sjimharris * list element. 316230557Sjimharris * 317230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 318230557Sjimharris * from which to retrieve the scatter gather list. 319230557Sjimharris * @param[in] ata_io This parameter specifies the user's ATA IO request 320230557Sjimharris * from which to retrieve the scatter gather list. 321230557Sjimharris * @param[in] current_sge This parameter specifies the current SG element 322230557Sjimharris * being pointed to. If retrieving the first element, 323230557Sjimharris * then this value should be NULL. 324230557Sjimharris * @param[in] next_sge This parameter is the returned SGL element 325230557Sjimharris * based on current_sge. 326230557Sjimharris * 327230557Sjimharris * @return This method returns a pointer to the scatter gather element. 328230557Sjimharris */ 329230557Sjimharrisvoid sati_cb_sgl_next_sge( 330230557Sjimharris void * scsi_io, 331230557Sjimharris void * ata_io, 332230557Sjimharris void * current_sge, 333230557Sjimharris void ** next_sge 334230557Sjimharris); 335230557Sjimharris 336230557Sjimharris/** 337230557Sjimharris * @brief This method will set the next scatter-gather elements address 338230557Sjimharris * low field. 339230557Sjimharris * 340230557Sjimharris * @param[in] current_sge This parameter specifies the current SG element 341230557Sjimharris * being pointed to. 342230557Sjimharris * @param[in] address_low This parameter specifies the lower 32-bits 343230557Sjimharris * of address to be programmed into the SG element. 344230557Sjimharris * @param[in] address_high This parameter specifies the upper 32-bits 345230557Sjimharris * of address to be programmed into the SG element. 346230557Sjimharris * @param[in] length This parameter specifies the number of bytes 347230557Sjimharris * to be programmed into the SG element. 348230557Sjimharris * 349230557Sjimharris * @return none 350230557Sjimharris */ 351230557Sjimharrisvoid sati_cb_sge_write( 352230557Sjimharris void * current_sge, 353230557Sjimharris U32 phys_address_low, 354230557Sjimharris U32 phys_address_high, 355230557Sjimharris U32 byte_length 356230557Sjimharris); 357230557Sjimharris 358230557Sjimharris/** 359230557Sjimharris * @brief This method will check to see if the translation requires 360230557Sjimharris * a translation response callback. Some translations need to be alerted on all 361230557Sjimharris * failures so sequence cleanup can be completed for halting the translation. 362230557Sjimharris * 363230557Sjimharris * @param[in] the current SCIC request under going translation. 364230557Sjimharris * 365230557Sjimharris * @return TRUE A response callback will be required to complete this translation sequence. 366230557Sjimharris */ 367230557SjimharrisBOOL sati_cb_do_translate_response( 368230557Sjimharris void * request 369230557Sjimharris); 370230557Sjimharris 371230557Sjimharris/** 372230557Sjimharris * @brief This method retrieves the SAS address for the device associated 373230557Sjimharris * with the supplied SCSI IO request. This method assumes that the 374230557Sjimharris * associated device is contained in a SAS Domain. 375230557Sjimharris * 376230557Sjimharris * @param[in] scsi_io This parameter specifies the user's SCSI IO request 377230557Sjimharris * for which to retreive the SAS address of the device. 378230557Sjimharris * @param[out] sas_address This parameter specifies the SAS address memory 379230557Sjimharris * to be contain the retrieved value. 380230557Sjimharris * 381230557Sjimharris * @return none 382230557Sjimharris */ 383230557Sjimharrisvoid sati_cb_device_get_sas_address( 384230557Sjimharris void * scsi_io, 385230557Sjimharris SCI_SAS_ADDRESS_T * sas_address 386230557Sjimharris); 387230557Sjimharris 388230557Sjimharris/** 389230557Sjimharris * @brief In this method the user is expected to log the supplied 390230557Sjimharris * error information. The user must be capable of handling variable 391230557Sjimharris * length argument lists and should consider prepending the fact 392230557Sjimharris * that this is an error from the core. 393230557Sjimharris * 394230557Sjimharris * @param[in] logger_object This parameter specifies the logger object 395230557Sjimharris * associated with this message. 396230557Sjimharris * @param[in] log_object_mask This parameter specifies the log objects 397230557Sjimharris * for which this message is being generated. 398230557Sjimharris * @param[in] log_message This parameter specifies the message to be logged. 399230557Sjimharris * 400230557Sjimharris * @return none 401230557Sjimharris */ 402230557Sjimharrisvoid sati_cb_logger_log_error( 403230557Sjimharris void * logger_object, 404230557Sjimharris U32 log_object_mask, 405230557Sjimharris char * log_message, 406230557Sjimharris ... 407230557Sjimharris); 408230557Sjimharris 409230557Sjimharris/** 410230557Sjimharris * @brief In this method the user is expected to log the supplied warning 411230557Sjimharris * information. The user must be capable of handling variable 412230557Sjimharris * length argument lists and should consider prepending the fact 413230557Sjimharris * that this is a warning from the core. 414230557Sjimharris * 415230557Sjimharris * @param[in] logger_object This parameter specifies the logger object 416230557Sjimharris * associated with this message. 417230557Sjimharris * @param[in] log_object_mask This parameter specifies the log objects 418230557Sjimharris * for which this message is being generated. 419230557Sjimharris * @param[in] log_message This parameter specifies the message to be logged. 420230557Sjimharris * 421230557Sjimharris * @return none 422230557Sjimharris */ 423230557Sjimharrisvoid sati_cb_logger_log_warning( 424230557Sjimharris void * logger_object, 425230557Sjimharris U32 log_object_mask, 426230557Sjimharris char * log_message, 427230557Sjimharris ... 428230557Sjimharris); 429230557Sjimharris 430230557Sjimharris/** 431230557Sjimharris * @brief In this method the user is expected to log the supplied debug 432230557Sjimharris * information. The user must be capable of handling variable 433230557Sjimharris * length argument lists and should consider prepending the fact 434230557Sjimharris * that this is a debug message from the core. 435230557Sjimharris * 436230557Sjimharris * @param[in] logger_object This parameter specifies the logger object 437230557Sjimharris * associated with this message. 438230557Sjimharris * @param[in] log_object_mask This parameter specifies the log objects 439230557Sjimharris * for which this message is being generated. 440230557Sjimharris * @param[in] log_message This parameter specifies the message to be logged. 441230557Sjimharris * 442230557Sjimharris * @return none 443230557Sjimharris */ 444230557Sjimharrisvoid sati_cb_logger_log_info( 445230557Sjimharris void * logger_object, 446230557Sjimharris U32 log_object_mask, 447230557Sjimharris char * log_message, 448230557Sjimharris ... 449230557Sjimharris); 450230557Sjimharris 451230557Sjimharris/** 452230557Sjimharris * @brief In this method the user is expected to log the supplied function 453230557Sjimharris * trace information. The user must be capable of handling variable 454230557Sjimharris * length argument lists and should consider prepending the fact 455230557Sjimharris * that this is a function trace (i.e. entry/exit) message from the 456230557Sjimharris * core. 457230557Sjimharris * 458230557Sjimharris * @param[in] logger_object This parameter specifies the logger object 459230557Sjimharris * associated with this message. 460230557Sjimharris * @param[in] log_object_mask This parameter specifies the log objects 461230557Sjimharris * for which this message is being generated. 462230557Sjimharris * @param[in] log_message This parameter specifies the message to be logged. 463230557Sjimharris * 464230557Sjimharris * @return none 465230557Sjimharris */ 466230557Sjimharrisvoid sati_cb_logger_log_trace( 467230557Sjimharris void * logger_object, 468230557Sjimharris U32 log_object_mask, 469230557Sjimharris char * log_message, 470230557Sjimharris ... 471230557Sjimharris); 472230557Sjimharris 473230557Sjimharris#include <dev/isci/scil/sati_callbacks_implementation.h> 474230557Sjimharris 475230557Sjimharris#else // SATI_DEFAULT_DECLARATION 476230557Sjimharris 477230557Sjimharris#include <dev/isci/scil/scif_sas_sati_binding.h> 478230557Sjimharris#endif // SATI_DEFAULT_DECLARATION 479230557Sjimharris 480230557Sjimharris#endif // _SATI_CALLBACKS_H_ 481230557Sjimharris 482