linux/drivers/scsi/ses.c
<<
>>
Prefs
   1/*
   2 * SCSI Enclosure Services
   3 *
   4 * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
   5 *
   6**-----------------------------------------------------------------------------
   7**
   8**  This program is free software; you can redistribute it and/or
   9**  modify it under the terms of the GNU General Public License
  10**  version 2 as published by the Free Software Foundation.
  11**
  12**  This program is distributed in the hope that it will be useful,
  13**  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15**  GNU General Public License for more details.
  16**
  17**  You should have received a copy of the GNU General Public License
  18**  along with this program; if not, write to the Free Software
  19**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20**
  21**-----------------------------------------------------------------------------
  22*/
  23
  24#include <linux/slab.h>
  25#include <linux/module.h>
  26#include <linux/kernel.h>
  27#include <linux/enclosure.h>
  28#include <asm/unaligned.h>
  29
  30#include <scsi/scsi.h>
  31#include <scsi/scsi_cmnd.h>
  32#include <scsi/scsi_dbg.h>
  33#include <scsi/scsi_device.h>
  34#include <scsi/scsi_driver.h>
  35#include <scsi/scsi_host.h>
  36
  37#include <scsi/scsi_transport_sas.h>
  38
  39struct ses_device {
  40        unsigned char *page1;
  41        unsigned char *page1_types;
  42        unsigned char *page2;
  43        unsigned char *page10;
  44        short page1_len;
  45        short page1_num_types;
  46        short page2_len;
  47        short page10_len;
  48};
  49
  50struct ses_component {
  51        u64 addr;
  52};
  53
  54static int ses_probe(struct device *dev)
  55{
  56        struct scsi_device *sdev = to_scsi_device(dev);
  57        int err = -ENODEV;
  58
  59        if (sdev->type != TYPE_ENCLOSURE)
  60                goto out;
  61
  62        err = 0;
  63        sdev_printk(KERN_NOTICE, sdev, "Attached Enclosure device\n");
  64
  65 out:
  66        return err;
  67}
  68
  69#define SES_TIMEOUT (30 * HZ)
  70#define SES_RETRIES 3
  71
  72static void init_device_slot_control(unsigned char *dest_desc,
  73                                     struct enclosure_component *ecomp,
  74                                     unsigned char *status)
  75{
  76        memcpy(dest_desc, status, 4);
  77        dest_desc[0] = 0;
  78        /* only clear byte 1 for ENCLOSURE_COMPONENT_DEVICE */
  79        if (ecomp->type == ENCLOSURE_COMPONENT_DEVICE)
  80                dest_desc[1] = 0;
  81        dest_desc[2] &= 0xde;
  82        dest_desc[3] &= 0x3c;
  83}
  84
  85
  86static int ses_recv_diag(struct scsi_device *sdev, int page_code,
  87                         void *buf, int bufflen)
  88{
  89        int ret;
  90        unsigned char cmd[] = {
  91                RECEIVE_DIAGNOSTIC,
  92                1,              /* Set PCV bit */
  93                page_code,
  94                bufflen >> 8,
  95                bufflen & 0xff,
  96                0
  97        };
  98        unsigned char recv_page_code;
  99
 100        ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
 101                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
 102        if (unlikely(!ret))
 103                return ret;
 104
 105        recv_page_code = ((unsigned char *)buf)[0];
 106
 107        if (likely(recv_page_code == page_code))
 108                return ret;
 109
 110        /* successful diagnostic but wrong page code.  This happens to some
 111         * USB devices, just print a message and pretend there was an error */
 112
 113        sdev_printk(KERN_ERR, sdev,
 114                    "Wrong diagnostic page; asked for %d got %u\n",
 115                    page_code, recv_page_code);
 116
 117        return -EINVAL;
 118}
 119
 120static int ses_send_diag(struct scsi_device *sdev, int page_code,
 121                         void *buf, int bufflen)
 122{
 123        u32 result;
 124
 125        unsigned char cmd[] = {
 126                SEND_DIAGNOSTIC,
 127                0x10,           /* Set PF bit */
 128                0,
 129                bufflen >> 8,
 130                bufflen & 0xff,
 131                0
 132        };
 133
 134        result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
 135                                  NULL, SES_TIMEOUT, SES_RETRIES, NULL);
 136        if (result)
 137                sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n",
 138                            result);
 139        return result;
 140}
 141
 142static int ses_set_page2_descriptor(struct enclosure_device *edev,
 143                                      struct enclosure_component *ecomp,
 144                                      unsigned char *desc)
 145{
 146        int i, j, count = 0, descriptor = ecomp->number;
 147        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 148        struct ses_device *ses_dev = edev->scratch;
 149        unsigned char *type_ptr = ses_dev->page1_types;
 150        unsigned char *desc_ptr = ses_dev->page2 + 8;
 151
 152        /* Clear everything */
 153        memset(desc_ptr, 0, ses_dev->page2_len - 8);
 154        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 155                for (j = 0; j < type_ptr[1]; j++) {
 156                        desc_ptr += 4;
 157                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 158                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 159                                continue;
 160                        if (count++ == descriptor) {
 161                                memcpy(desc_ptr, desc, 4);
 162                                /* set select */
 163                                desc_ptr[0] |= 0x80;
 164                                /* clear reserved, just in case */
 165                                desc_ptr[0] &= 0xf0;
 166                        }
 167                }
 168        }
 169
 170        return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 171}
 172
 173static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
 174                                      struct enclosure_component *ecomp)
 175{
 176        int i, j, count = 0, descriptor = ecomp->number;
 177        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 178        struct ses_device *ses_dev = edev->scratch;
 179        unsigned char *type_ptr = ses_dev->page1_types;
 180        unsigned char *desc_ptr = ses_dev->page2 + 8;
 181
 182        ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 183
 184        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 185                for (j = 0; j < type_ptr[1]; j++) {
 186                        desc_ptr += 4;
 187                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 188                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 189                                continue;
 190                        if (count++ == descriptor)
 191                                return desc_ptr;
 192                }
 193        }
 194        return NULL;
 195}
 196
 197/* For device slot and array device slot elements, byte 3 bit 6
 198 * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this
 199 * code stands these bits are shifted 4 positions right so in
 200 * sysfs they will appear as bits 2 and 1 respectively. Strange. */
 201static void ses_get_fault(struct enclosure_device *edev,
 202                          struct enclosure_component *ecomp)
 203{
 204        unsigned char *desc;
 205
 206        desc = ses_get_page2_descriptor(edev, ecomp);
 207        if (desc)
 208                ecomp->fault = (desc[3] & 0x60) >> 4;
 209}
 210
 211static int ses_set_fault(struct enclosure_device *edev,
 212                          struct enclosure_component *ecomp,
 213                         enum enclosure_component_setting val)
 214{
 215        unsigned char desc[4];
 216        unsigned char *desc_ptr;
 217
 218        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 219
 220        if (!desc_ptr)
 221                return -EIO;
 222
 223        init_device_slot_control(desc, ecomp, desc_ptr);
 224
 225        switch (val) {
 226        case ENCLOSURE_SETTING_DISABLED:
 227                desc[3] &= 0xdf;
 228                break;
 229        case ENCLOSURE_SETTING_ENABLED:
 230                desc[3] |= 0x20;
 231                break;
 232        default:
 233                /* SES doesn't do the SGPIO blink settings */
 234                return -EINVAL;
 235        }
 236
 237        return ses_set_page2_descriptor(edev, ecomp, desc);
 238}
 239
 240static void ses_get_status(struct enclosure_device *edev,
 241                           struct enclosure_component *ecomp)
 242{
 243        unsigned char *desc;
 244
 245        desc = ses_get_page2_descriptor(edev, ecomp);
 246        if (desc)
 247                ecomp->status = (desc[0] & 0x0f);
 248}
 249
 250static void ses_get_locate(struct enclosure_device *edev,
 251                           struct enclosure_component *ecomp)
 252{
 253        unsigned char *desc;
 254
 255        desc = ses_get_page2_descriptor(edev, ecomp);
 256        if (desc)
 257                ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
 258}
 259
 260static int ses_set_locate(struct enclosure_device *edev,
 261                          struct enclosure_component *ecomp,
 262                          enum enclosure_component_setting val)
 263{
 264        unsigned char desc[4];
 265        unsigned char *desc_ptr;
 266
 267        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 268
 269        if (!desc_ptr)
 270                return -EIO;
 271
 272        init_device_slot_control(desc, ecomp, desc_ptr);
 273
 274        switch (val) {
 275        case ENCLOSURE_SETTING_DISABLED:
 276                desc[2] &= 0xfd;
 277                break;
 278        case ENCLOSURE_SETTING_ENABLED:
 279                desc[2] |= 0x02;
 280                break;
 281        default:
 282                /* SES doesn't do the SGPIO blink settings */
 283                return -EINVAL;
 284        }
 285        return ses_set_page2_descriptor(edev, ecomp, desc);
 286}
 287
 288static int ses_set_active(struct enclosure_device *edev,
 289                          struct enclosure_component *ecomp,
 290                          enum enclosure_component_setting val)
 291{
 292        unsigned char desc[4];
 293        unsigned char *desc_ptr;
 294
 295        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 296
 297        if (!desc_ptr)
 298                return -EIO;
 299
 300        init_device_slot_control(desc, ecomp, desc_ptr);
 301
 302        switch (val) {
 303        case ENCLOSURE_SETTING_DISABLED:
 304                desc[2] &= 0x7f;
 305                ecomp->active = 0;
 306                break;
 307        case ENCLOSURE_SETTING_ENABLED:
 308                desc[2] |= 0x80;
 309                ecomp->active = 1;
 310                break;
 311        default:
 312                /* SES doesn't do the SGPIO blink settings */
 313                return -EINVAL;
 314        }
 315        return ses_set_page2_descriptor(edev, ecomp, desc);
 316}
 317
 318static int ses_show_id(struct enclosure_device *edev, char *buf)
 319{
 320        struct ses_device *ses_dev = edev->scratch;
 321        unsigned long long id = get_unaligned_be64(ses_dev->page1+8+4);
 322
 323        return sprintf(buf, "%#llx\n", id);
 324}
 325
 326static void ses_get_power_status(struct enclosure_device *edev,
 327                                 struct enclosure_component *ecomp)
 328{
 329        unsigned char *desc;
 330
 331        desc = ses_get_page2_descriptor(edev, ecomp);
 332        if (desc)
 333                ecomp->power_status = (desc[3] & 0x10) ? 0 : 1;
 334}
 335
 336static int ses_set_power_status(struct enclosure_device *edev,
 337                                struct enclosure_component *ecomp,
 338                                int val)
 339{
 340        unsigned char desc[4];
 341        unsigned char *desc_ptr;
 342
 343        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 344
 345        if (!desc_ptr)
 346                return -EIO;
 347
 348        init_device_slot_control(desc, ecomp, desc_ptr);
 349
 350        switch (val) {
 351        /* power = 1 is device_off = 0 and vice versa */
 352        case 0:
 353                desc[3] |= 0x10;
 354                break;
 355        case 1:
 356                desc[3] &= 0xef;
 357                break;
 358        default:
 359                return -EINVAL;
 360        }
 361        ecomp->power_status = val;
 362        return ses_set_page2_descriptor(edev, ecomp, desc);
 363}
 364
 365static struct enclosure_component_callbacks ses_enclosure_callbacks = {
 366        .get_fault              = ses_get_fault,
 367        .set_fault              = ses_set_fault,
 368        .get_status             = ses_get_status,
 369        .get_locate             = ses_get_locate,
 370        .set_locate             = ses_set_locate,
 371        .get_power_status       = ses_get_power_status,
 372        .set_power_status       = ses_set_power_status,
 373        .set_active             = ses_set_active,
 374        .show_id                = ses_show_id,
 375};
 376
 377struct ses_host_edev {
 378        struct Scsi_Host *shost;
 379        struct enclosure_device *edev;
 380};
 381
 382#if 0
 383int ses_match_host(struct enclosure_device *edev, void *data)
 384{
 385        struct ses_host_edev *sed = data;
 386        struct scsi_device *sdev;
 387
 388        if (!scsi_is_sdev_device(edev->edev.parent))
 389                return 0;
 390
 391        sdev = to_scsi_device(edev->edev.parent);
 392
 393        if (sdev->host != sed->shost)
 394                return 0;
 395
 396        sed->edev = edev;
 397        return 1;
 398}
 399#endif  /*  0  */
 400
 401static void ses_process_descriptor(struct enclosure_component *ecomp,
 402                                   unsigned char *desc)
 403{
 404        int eip = desc[0] & 0x10;
 405        int invalid = desc[0] & 0x80;
 406        enum scsi_protocol proto = desc[0] & 0x0f;
 407        u64 addr = 0;
 408        int slot = -1;
 409        struct ses_component *scomp = ecomp->scratch;
 410        unsigned char *d;
 411
 412        if (invalid)
 413                return;
 414
 415        switch (proto) {
 416        case SCSI_PROTOCOL_FCP:
 417                if (eip) {
 418                        d = desc + 4;
 419                        slot = d[3];
 420                }
 421                break;
 422        case SCSI_PROTOCOL_SAS:
 423                if (eip) {
 424                        d = desc + 4;
 425                        slot = d[3];
 426                        d = desc + 8;
 427                } else
 428                        d = desc + 4;
 429                /* only take the phy0 addr */
 430                addr = (u64)d[12] << 56 |
 431                        (u64)d[13] << 48 |
 432                        (u64)d[14] << 40 |
 433                        (u64)d[15] << 32 |
 434                        (u64)d[16] << 24 |
 435                        (u64)d[17] << 16 |
 436                        (u64)d[18] << 8 |
 437                        (u64)d[19];
 438                break;
 439        default:
 440                /* FIXME: Need to add more protocols than just SAS */
 441                break;
 442        }
 443        ecomp->slot = slot;
 444        scomp->addr = addr;
 445}
 446
 447struct efd {
 448        u64 addr;
 449        struct device *dev;
 450};
 451
 452static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
 453                                      void *data)
 454{
 455        struct efd *efd = data;
 456        int i;
 457        struct ses_component *scomp;
 458
 459        if (!edev->component[0].scratch)
 460                return 0;
 461
 462        for (i = 0; i < edev->components; i++) {
 463                scomp = edev->component[i].scratch;
 464                if (scomp->addr != efd->addr)
 465                        continue;
 466
 467                if (enclosure_add_device(edev, i, efd->dev) == 0)
 468                        kobject_uevent(&efd->dev->kobj, KOBJ_CHANGE);
 469                return 1;
 470        }
 471        return 0;
 472}
 473
 474#define INIT_ALLOC_SIZE 32
 475
 476static void ses_enclosure_data_process(struct enclosure_device *edev,
 477                                       struct scsi_device *sdev,
 478                                       int create)
 479{
 480        u32 result;
 481        unsigned char *buf = NULL, *type_ptr, *desc_ptr, *addl_desc_ptr = NULL;
 482        int i, j, page7_len, len, components;
 483        struct ses_device *ses_dev = edev->scratch;
 484        int types = ses_dev->page1_num_types;
 485        unsigned char *hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 486
 487        if (!hdr_buf)
 488                goto simple_populate;
 489
 490        /* re-read page 10 */
 491        if (ses_dev->page10)
 492                ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len);
 493        /* Page 7 for the descriptors is optional */
 494        result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
 495        if (result)
 496                goto simple_populate;
 497
 498        page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 499        /* add 1 for trailing '\0' we'll use */
 500        buf = kzalloc(len + 1, GFP_KERNEL);
 501        if (!buf)
 502                goto simple_populate;
 503        result = ses_recv_diag(sdev, 7, buf, len);
 504        if (result) {
 505 simple_populate:
 506                kfree(buf);
 507                buf = NULL;
 508                desc_ptr = NULL;
 509                len = 0;
 510                page7_len = 0;
 511        } else {
 512                desc_ptr = buf + 8;
 513                len = (desc_ptr[2] << 8) + desc_ptr[3];
 514                /* skip past overall descriptor */
 515                desc_ptr += len + 4;
 516        }
 517        if (ses_dev->page10)
 518                addl_desc_ptr = ses_dev->page10 + 8;
 519        type_ptr = ses_dev->page1_types;
 520        components = 0;
 521        for (i = 0; i < types; i++, type_ptr += 4) {
 522                for (j = 0; j < type_ptr[1]; j++) {
 523                        char *name = NULL;
 524                        struct enclosure_component *ecomp;
 525
 526                        if (desc_ptr) {
 527                                if (desc_ptr >= buf + page7_len) {
 528                                        desc_ptr = NULL;
 529                                } else {
 530                                        len = (desc_ptr[2] << 8) + desc_ptr[3];
 531                                        desc_ptr += 4;
 532                                        /* Add trailing zero - pushes into
 533                                         * reserved space */
 534                                        desc_ptr[len] = '\0';
 535                                        name = desc_ptr;
 536                                }
 537                        }
 538                        if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 539                            type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
 540
 541                                if (create)
 542                                        ecomp = enclosure_component_alloc(
 543                                                edev,
 544                                                components++,
 545                                                type_ptr[0],
 546                                                name);
 547                                else
 548                                        ecomp = &edev->component[components++];
 549
 550                                if (!IS_ERR(ecomp)) {
 551                                        ses_get_power_status(edev, ecomp);
 552                                        if (addl_desc_ptr)
 553                                                ses_process_descriptor(
 554                                                        ecomp,
 555                                                        addl_desc_ptr);
 556                                        if (create)
 557                                                enclosure_component_register(
 558                                                        ecomp);
 559                                }
 560                        }
 561                        if (desc_ptr)
 562                                desc_ptr += len;
 563
 564                        if (addl_desc_ptr &&
 565                            /* only find additional descriptions for specific devices */
 566                            (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 567                             type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
 568                             type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
 569                             /* these elements are optional */
 570                             type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
 571                             type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
 572                             type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
 573                                addl_desc_ptr += addl_desc_ptr[1] + 2;
 574
 575                }
 576        }
 577        kfree(buf);
 578        kfree(hdr_buf);
 579}
 580
 581static void ses_match_to_enclosure(struct enclosure_device *edev,
 582                                   struct scsi_device *sdev)
 583{
 584        struct efd efd = {
 585                .addr = 0,
 586        };
 587
 588        ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
 589
 590        if (scsi_is_sas_rphy(&sdev->sdev_gendev))
 591                efd.addr = sas_get_address(sdev);
 592
 593        if (efd.addr) {
 594                efd.dev = &sdev->sdev_gendev;
 595
 596                enclosure_for_each_device(ses_enclosure_find_by_addr, &efd);
 597        }
 598}
 599
 600static int ses_intf_add(struct device *cdev,
 601                        struct class_interface *intf)
 602{
 603        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 604        struct scsi_device *tmp_sdev;
 605        unsigned char *buf = NULL, *hdr_buf, *type_ptr;
 606        struct ses_device *ses_dev;
 607        u32 result;
 608        int i, types, len, components = 0;
 609        int err = -ENOMEM;
 610        int num_enclosures;
 611        struct enclosure_device *edev;
 612        struct ses_component *scomp = NULL;
 613
 614        if (!scsi_device_enclosure(sdev)) {
 615                /* not an enclosure, but might be in one */
 616                struct enclosure_device *prev = NULL;
 617
 618                while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 619                        ses_match_to_enclosure(edev, sdev);
 620                        prev = edev;
 621                }
 622                return -ENODEV;
 623        }
 624
 625        /* TYPE_ENCLOSURE prints a message in probe */
 626        if (sdev->type != TYPE_ENCLOSURE)
 627                sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n");
 628
 629        ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL);
 630        hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 631        if (!hdr_buf || !ses_dev)
 632                goto err_init_free;
 633
 634        result = ses_recv_diag(sdev, 1, hdr_buf, INIT_ALLOC_SIZE);
 635        if (result)
 636                goto recv_failed;
 637
 638        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 639        buf = kzalloc(len, GFP_KERNEL);
 640        if (!buf)
 641                goto err_free;
 642
 643        result = ses_recv_diag(sdev, 1, buf, len);
 644        if (result)
 645                goto recv_failed;
 646
 647        types = 0;
 648
 649        /* we always have one main enclosure and the rest are referred
 650         * to as secondary subenclosures */
 651        num_enclosures = buf[1] + 1;
 652
 653        /* begin at the enclosure descriptor */
 654        type_ptr = buf + 8;
 655        /* skip all the enclosure descriptors */
 656        for (i = 0; i < num_enclosures && type_ptr < buf + len; i++) {
 657                types += type_ptr[2];
 658                type_ptr += type_ptr[3] + 4;
 659        }
 660
 661        ses_dev->page1_types = type_ptr;
 662        ses_dev->page1_num_types = types;
 663
 664        for (i = 0; i < types && type_ptr < buf + len; i++, type_ptr += 4) {
 665                if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 666                    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 667                        components += type_ptr[1];
 668        }
 669        ses_dev->page1 = buf;
 670        ses_dev->page1_len = len;
 671        buf = NULL;
 672
 673        result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE);
 674        if (result)
 675                goto recv_failed;
 676
 677        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 678        buf = kzalloc(len, GFP_KERNEL);
 679        if (!buf)
 680                goto err_free;
 681
 682        /* make sure getting page 2 actually works */
 683        result = ses_recv_diag(sdev, 2, buf, len);
 684        if (result)
 685                goto recv_failed;
 686        ses_dev->page2 = buf;
 687        ses_dev->page2_len = len;
 688        buf = NULL;
 689
 690        /* The additional information page --- allows us
 691         * to match up the devices */
 692        result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
 693        if (!result) {
 694
 695                len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 696                buf = kzalloc(len, GFP_KERNEL);
 697                if (!buf)
 698                        goto err_free;
 699
 700                result = ses_recv_diag(sdev, 10, buf, len);
 701                if (result)
 702                        goto recv_failed;
 703                ses_dev->page10 = buf;
 704                ses_dev->page10_len = len;
 705                buf = NULL;
 706        }
 707        scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
 708        if (!scomp)
 709                goto err_free;
 710
 711        edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
 712                                  components, &ses_enclosure_callbacks);
 713        if (IS_ERR(edev)) {
 714                err = PTR_ERR(edev);
 715                goto err_free;
 716        }
 717
 718        kfree(hdr_buf);
 719
 720        edev->scratch = ses_dev;
 721        for (i = 0; i < components; i++)
 722                edev->component[i].scratch = scomp + i;
 723
 724        ses_enclosure_data_process(edev, sdev, 1);
 725
 726        /* see if there are any devices matching before
 727         * we found the enclosure */
 728        shost_for_each_device(tmp_sdev, sdev->host) {
 729                if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
 730                        continue;
 731                ses_match_to_enclosure(edev, tmp_sdev);
 732        }
 733
 734        return 0;
 735
 736 recv_failed:
 737        sdev_printk(KERN_ERR, sdev, "Failed to get diagnostic page 0x%x\n",
 738                    result);
 739        err = -ENODEV;
 740 err_free:
 741        kfree(buf);
 742        kfree(scomp);
 743        kfree(ses_dev->page10);
 744        kfree(ses_dev->page2);
 745        kfree(ses_dev->page1);
 746 err_init_free:
 747        kfree(ses_dev);
 748        kfree(hdr_buf);
 749        sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n", err);
 750        return err;
 751}
 752
 753static int ses_remove(struct device *dev)
 754{
 755        return 0;
 756}
 757
 758static void ses_intf_remove_component(struct scsi_device *sdev)
 759{
 760        struct enclosure_device *edev, *prev = NULL;
 761
 762        while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 763                prev = edev;
 764                if (!enclosure_remove_device(edev, &sdev->sdev_gendev))
 765                        break;
 766        }
 767        if (edev)
 768                put_device(&edev->edev);
 769}
 770
 771static void ses_intf_remove_enclosure(struct scsi_device *sdev)
 772{
 773        struct enclosure_device *edev;
 774        struct ses_device *ses_dev;
 775
 776        /*  exact match to this enclosure */
 777        edev = enclosure_find(&sdev->sdev_gendev, NULL);
 778        if (!edev)
 779                return;
 780
 781        enclosure_unregister(edev);
 782
 783        ses_dev = edev->scratch;
 784        edev->scratch = NULL;
 785
 786        kfree(ses_dev->page10);
 787        kfree(ses_dev->page1);
 788        kfree(ses_dev->page2);
 789        kfree(ses_dev);
 790
 791        kfree(edev->component[0].scratch);
 792
 793        put_device(&edev->edev);
 794}
 795
 796static void ses_intf_remove(struct device *cdev,
 797                            struct class_interface *intf)
 798{
 799        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 800
 801        if (!scsi_device_enclosure(sdev))
 802                ses_intf_remove_component(sdev);
 803        else
 804                ses_intf_remove_enclosure(sdev);
 805}
 806
 807static struct class_interface ses_interface = {
 808        .add_dev        = ses_intf_add,
 809        .remove_dev     = ses_intf_remove,
 810};
 811
 812static struct scsi_driver ses_template = {
 813        .gendrv = {
 814                .name           = "ses",
 815                .owner          = THIS_MODULE,
 816                .probe          = ses_probe,
 817                .remove         = ses_remove,
 818        },
 819};
 820
 821static int __init ses_init(void)
 822{
 823        int err;
 824
 825        err = scsi_register_interface(&ses_interface);
 826        if (err)
 827                return err;
 828
 829        err = scsi_register_driver(&ses_template.gendrv);
 830        if (err)
 831                goto out_unreg;
 832
 833        return 0;
 834
 835 out_unreg:
 836        scsi_unregister_interface(&ses_interface);
 837        return err;
 838}
 839
 840static void __exit ses_exit(void)
 841{
 842        scsi_unregister_driver(&ses_template.gendrv);
 843        scsi_unregister_interface(&ses_interface);
 844}
 845
 846module_init(ses_init);
 847module_exit(ses_exit);
 848
 849MODULE_ALIAS_SCSI_DEVICE(TYPE_ENCLOSURE);
 850
 851MODULE_AUTHOR("James Bottomley");
 852MODULE_DESCRIPTION("SCSI Enclosure Services (ses) driver");
 853MODULE_LICENSE("GPL v2");
 854